GetDIBits帮助

时间:2011-09-21 12:34:05

标签: c++ c gdi winsock

我试图使用此代码使用getDIBits获取1bpp位图的位:

HDC dcmem=NULL;
PBYTE buf=NULL;
LPBITMAPINFO bmpInfo;
HBITMAP bmpfile = NULL;
int dibLineCount;

//load bitmap
bmpfile = (HBITMAP)LoadImageA(NULL, FILENAME, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 
if(!bmpfile) 
{   
    //Load Image failed
       return 0;      
}

//select bitmap to dc   
dcmem = CreateCompatibleDC ( NULL );    
if (NULL==SelectObject(dcmem,bmpfile))
{   
    //select object failed
    DeleteDC(dcmem); 
    return 0; 
}


bmpInfo = (LPBITMAPINFO)calloc(1,sizeof(BITMAPINFO));
bmpInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

//getDIBits to fill bmpInfo
dibLineCount = GetDIBits(dcmem,bmpfile,0,0,NULL,bmpInfo,DIB_RGB_COLORS);
if(dibLineCount == 0)
{
    //getdibits 1 failed
    DeleteDC(dcmem);
    free(bmpInfo);
    return 0;   
}

if(bmpInfo->bmiHeader.biSizeImage <= 0)
    bmpInfo->bmiHeader.biSizeImage=bmpInfo->bmiHeader.biWidth*abs(bmpInfo->bmiHeader.biHeight)*(bmpInfo->bmiHeader.biBitCount+7)/8;


if((buf = (PBYTE)malloc(bmpInfo->bmiHeader.biSizeImage)) == NULL)
    return 0;

bmpInfo->bmiHeader.biCompression =BI_RGB;

//get bits
dibLineCount = GetDIBits(dcmem,bmpfile,0,bmpInfo->bmiHeader.biHeight,buf,bmpInfo,DIB_RGB_COLORS);
if(dibLineCount == 0)
{
    //getdibits 2 failed
    DeleteDC(0,dcmem);
    free(buf);
    free(bmpInfo);
    return 0;
}

然后我使用winsock将这些位发送到另一台PC。但是每当我发送带有比特的数据包时,我看到这些比特只包含句子&#34; ...&#34;或十六进制的FF,非常奇怪。我看到第二次调用getDIBits会返回正确的扫描行数。任何人都可以帮助我为什么这些位是这样的?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

当您第一次调用GetDIBits时,您将获得兼容DC的像素格式而不是原始像素格式。在DC中选择位图不会将DC设置为使用位图的像素格式,它会将位图转换为屏幕格式。 (我怀疑你加载图像的方式也会将位图转换为屏幕的像素格式。)

加载位图时,您可能希望通过将LR_CREATEDIBSECTION添加到LoadImage中的选项来将其加载为DIBSECTION。这将使这些位保持原始像素格式。

如果您希望以特定像素格式输出比特,则应手动将bmpInfo结构初始化为所需格式,然后调用GetDIBits

如果您想要原始文件的像素格式的位,您可能甚至不需要GetDIBits。如果在LoadImage上使用LR_CREATEDIBSECTION,则可以使用GetObject来获取DIBSECTION,其中包含格式(可能是指向位的指针)。