获取DIBits帮助
我正在尝试使用以下代码使用 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。但是每次我发送带有位的数据包时,我都会看到这些位仅包含十六进制的句点“...”或 FF,这非常奇怪。我看到对 getDIBits 的第二次调用返回了正确的扫描行数。谁能帮我看看为什么这些位是这样的?任何帮助将不胜感激。
I'm trying to get the bits of a 1bpp bitmap using getDIBits using this code:
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;
}
Then I send the bits using winsock to another PC. But everytime I send the packet with the bits I see the bits only contain periods "..." or FF in hex which is very weird. I see that the second call to getDIBits returns the correct amount of lines scanned though. Can anyone help me why the bits are like this? Any help would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您第一次调用 GetDIBits 时,您将获得兼容 DC 的像素格式,而不是原始像素格式。将位图选择到 DC 中不会将 DC 设置为使用位图的像素格式,而是将位图转换为屏幕格式。 (我怀疑您加载图像的方式也会将位图转换为屏幕的像素格式。)
当您加载位图时,您可能希望通过将 LR_CREATEDIBSECTION 添加到 加载图像。这将使这些位保持其原始像素格式。
如果您希望以特定像素格式输出位,则应手动将 bmpInfo 结构初始化为您想要的格式,然后调用 GetDIBits。
如果您想要原始文件的像素格式的位,您可能甚至不需要 GetDIBits。如果在 LoadImage 上使用 LR_CREATEDIBSECTION,则可以使用 GetObject 获取 DIBSECTION,其中包含格式(可能还有指向位的指针)。
You're getting the pixel format of the compatible DC instead of the original pixel format, when you first call GetDIBits. Selecting the bitmap into the DC doesn't set up the DC to use the pixel format of the bitmap, it converts the bitmap to the format of the screen. (I suspect the way you're loading the image also converts the bitmap to the pixel format of the screen.)
When you load the bitmap, you probably want to load it as a DIBSECTION by adding LR_CREATEDIBSECTION to the options in LoadImage. This will keep the bits in their original pixel format.
If you want the bits out in a particular pixel format, you should manually initialize the bmpInfo structure to the format you want and then call GetDIBits.
If you want the bits in the pixel format of the original file, you probably don't even need GetDIBits. If you use LR_CREATEDIBSECTION on the LoadImage, you can then use GetObject to get the DIBSECTION, which has the format in it (and probably a pointer to the bits).