CreateBitmapIndirect 函数创建位图失败

来源:互联网 发布:网络侦探练哪些 编辑:程序博客网 时间:2024/06/03 16:50

CBitmap::CreateBitmapIndirect 函数创建位图成功却在CDC::SelectObject 选择位图时却失败,原因是CreateBitmapIndirect不能创建彩色位图,只能创建单色位图,虽然CreateBitmapIndirect创建彩色位图时也能返回成功,但用CDC::SelectObject 的时候失败。

MSDN只有在CreateBitmapIndirect 有说明:

While the CreateBitmapIndirect function can be used to create color bitmaps, for performance reasons applications should use CreateBitmapIndirect to create monochrome bitmaps and CreateCompatibleBitmap to create color bitmaps. Whenever a color bitmap from CreateBitmapIndirect is selected into a device context, the system must ensure that the bitmap matches the format of the device context it is being selected into. Because CreateCompatibleBitmap takes a device context, it returns a bitmap that has the same format as the specified device context. Thus, subsequent calls to SelectObject are faster with a color bitmap from CreateCompatibleBitmap than with a color bitmap returned from CreateBitmapIndirect.

虽然CreateBitmapIndirect函数可用于创建彩色位图,出于性能方面的应用程序应该使用CreateBitmapIndirect创建单色位图,用CreateCompatibleBitmap创建彩色位图...............................


要创建彩色位图应用 CreateCompatibleBitmap 函数


关于CreateBitmapIndirect  BITMAP参数的bmBits 创建成功后返回0的问题

CBitmap::CreateBitmapIndirect函数的功能是用一个BITMAP结构体重的高度、宽度和位模式(如果指定了一个的话)来初始化一个位图。调用该函数时,用户可以设置bmBits字段为NULL或者设为像素位数据的地址(用以初始化该位图)。 


如您的代码那样,在执行了CBitmap::GetBitmap之后所得的bm.bmBits确实为NULL,为了获得bmBits,您可以调用专门的CBitmap::GetBitmapBits函数来获得位数据。


BYTE bitbuffer[16]; 
DWORD ret3 = m_aBmp.GetBitmapBits(16, (LPVOID)bitbuffer);//检查bitbuffer中内容,的确是原来的位数据 




BITMAP bmWidthBytes  计算方法

typedef    struct    tagBITMAP    {                    LONG    bmType;                //必需为0              LONG    bmWidth;              //位图的宽度(以像素为单位)              LONG    bmHeight;            //位图的高度(以像素为单位)                  /*指定每条光栅所占字节数。此值必须取偶数,                 因为图形设备接口(GDI)默认为一个位图的位值组成一个2字节的整数数组。*/              LONG    bmWidthBytes;                    WORD    bmPlanes;            //    位图调色板颜色数                  WORD    bmBitsPixel;      //    一个点在每个调色板上接近的颜色位数                  LPVOID    bmBits;            //   指向存储像素阵列的数组          }    BITMAP;

bmWidthBytes : 一行像素所占的字节数,一行像素的存储必须按word对齐,所以该值必须为2的倍数。




单色图像 bmWidthBytes =bmWidth/8+(bmWidth/8)%2


256(8位)色图像 bmWidthBytes=bmWidth+bmWidth%2;


16色图像 bmWidthBytes=bmWidth/2+(bmWidth/2)%2;

r,g,b分量的存放位置

如果位图已经通过LoadBitmap加载到内存,则内存中的图像与显示设备紧密相关,比如原图是彩色图片,显示器是黑白色,通过bmp.LoadBitmap(我的图片)后,内存中的图像数据是黑白色的数据,而且还与显示器位数有关。如果需要在原位图数据上进行图像处理,就不要bmp.LoadBitmap来加载位图,而是打开文件获取位图数据。如果仅仅是在当前显示设备下进行效果处理,则可以使用bmp.LoadBitmap加载位图,通过CBitmap的GetBitmapBit函数可以获取位图数据,如果是24位显示器,则每3个字节表示一个像素,其中第一个字节是B,第二个字节是G,第3个字节是R;如果是32位的显示器,每4个字节表示一个像素,一般前3个字节与24位显示器一样,第4个字节一般没有什么意义。


0 0