Windows DIB文件操作详解-2.DIB转DDB

上一节讲到显示DIB的显示时需要将文件内容读到内存中(如下图),当使用SetDIBitsToDevice和StretchDIBits函数显示时中间涉及到一系列的转换,这样大大增加了性能消耗,特别是在重复显示的时候,每一次都要重新转换和显示。我们在想能不能找到一种办法减少这种消耗。很自然想到一次转换多处使用这种方法。那么应该将DIB转换成什么呢,观察下图,最后显示的其实就是DDB,我们把DIB转换成DDB,这样以后显示的时候直接使用转换的结果DDB即可。



DIB转DDB使用函数CreateDIBitmap,该函数定义如下

HBITMAP CreateDIBitmap(
  HDC hdc,                        // handle to DC
  CONST BITMAPINFOHEADER *lpbmih, // bitmap data
  DWORD fdwInit,                  // initialization option
  CONST VOID *lpbInit,            // initialization data
  CONST BITMAPINFO *lpbmi,        // color-format data
  UINT fuUsage                    // color-data usage
);

具体详细参数含义参见MSDN,这里只讲用法


这个函数Petzold给出了一个实现,步骤如下

1.利用lpbmih信息和hdc创建一个兼容DDB

2.如果指定了fdwInit为CBM_INIT,则创建一个hdc兼容DC并选入之前的兼容DDB

3.如果指定了fdwInit为CBM_INIT,利用SetDIBitsToDevice函数在之前的兼容DC上显示,这里使用了DIB的lpbInit、lpbmi、fuUsage参数


注意这里BITMAPINFOHEADER *lpbmih参数只是为了提供创建DDB时的信息(主要是位图大小),BITMAPINFO *lpbmi是作为SetDIBitsToDevice的参数使用的,可能包含有调试板信息。

如果传入的hdc为NULL则创建的是单色DDB,如果传入的是正常设备hdc,则创建的是设备格式DDB。

可以选择fdwInit参数为CBM_INIT在创建DDB时填充数据,也可以不使用CBM_INIT在创建完成后使用SetDIBits填充数据,这时候DIB的lpbInit、lpbmi、fuUsage参数均不需要


SetDIBits参数定义如下

int SetDIBits(
  HDC hdc,                  // handle to DC
  HBITMAP hbmp,             // handle to bitmap
  UINT uStartScan,          // starting scan line
  UINT cScanLines,          // number of scan lines
  CONST VOID *lpvBits,      // array of bitmap bits
  CONST BITMAPINFO *lpbmi,  // bitmap data
  UINT fuColorUse           // type of color indexes to use
);
显然这个就是在SetDIBitsToDevice函数上修改了一下作为填充数据用,实际上就是上面说的步骤的第三步。但是注意这里的hdc参数并不是在内存DC上显示用的hdc,只是作为DIB向DDB转换时提供调色板信息,当最后一个参数为DIB_PAL_COLORS参数时才需要。


这里只为强调DIB转DDB的使用方法和注意事项,具体的代码这里不再演示,参见Petzold的DIBCONV这个程序足以。


原创,转载请注明来自http://blog.csdn.net/wenzhou1219

你可能感兴趣的:(位图,DDB,DIB,CreateDIBitmap,SetDIBits)