上一节讲到DIB转换成DDB以提高位图显示性能,那么这里自然想到DDB转DIB。DDB转DIB有什么用呢?最常见的应用场合就是你得到了一个屏幕截图的DDB,现在想把它保存到磁盘上,这时候就要用到DDB转DIB函数GetDIBits。

1.GetDIBits使用方法

函数定义如下
int GetDIBits(HDC hdc,           // handle to DCHBITMAP hbmp,      // handle to bitmapUINT uStartScan,   // first scan line to setUINT cScanLines,   // number of scan lines to copyLPVOID lpvBits,    // array for bitmap bitsLPBITMAPINFO lpbi, // bitmap data bufferUINT uUsage        // RGB or palette index
);

这个函数获得hbmp的位图信息和数据填充到提前分配好的lpvBits和lpbi指针指向的内存中,完成DDB到DIB转换。

这个函数的使用步骤如下
1.定义BITMAPINFOHEADER bmih结构,设置结构的size,设置bitcount为0。lpvBits参数设为NULL而lpbi参数设为&bmih,如此调用GetDIBits函数,此函数会将hbmp的相关信息(大小、深度等信息)填充到bmih结构。
2.按照步骤1得到的信息分配lpbi和lpvBits结构内存。原则上当lpvBits结构lpvBits不为NULL时,lpbi的前6个参数必须设置,这里直接将bmih内容复制给lpbi。
3.传入分配好的lpbi和lpvBits结构内存地址,调用GetDIBits函数得到位图信息和数据。
一定要注意这里的lpvBits和lpbi内存是自己在调用函数前分配的。

2.屏幕截图保存到文件

这里贴上一个笔者写的截图软件中的屏幕截图DDB转DIB的实例代码,建议下载完整源代码查看
BOOL CScreenBitmap::ExportToFile(CDC *pDC, TCHAR *szBmpName,  RECT *pRect/*=NULL*/)
{HBITMAP hExportBmp;BITMAPFILEHEADER bmfh={0};/************************************************************************//* 获得数据                                                                     *//************************************************************************///获得要导出的DDB位图hExportBmp = CopyBitmap(pRect);//获得DDB信息BITMAPINFOHEADER bmih={0};bmih.biSize = sizeof(BITMAPINFOHEADER);bmih.biBitCount = 0;if (0 == GetDIBits(pDC->GetSafeHdc(), hExportBmp, 0, 0, NULL, (BITMAPINFO *)&bmih, DIB_RGB_COLORS)){return FALSE;}//删除已经分配的存储区if (NULL != m_pbmi){free(m_pbmi);m_pbmi = NULL;}if (NULL != m_pBits){free(m_pBits);m_pBits = NULL;}//分配新的存储区DWORD dwInfoSize;DWORD dwBitsSize;if (bmih.biBitCount>=16 && BI_BITFIELDS==bmih.biCompression){dwInfoSize = sizeof(BITMAPINFOHEADER) + 4*4;//字节对齐,RGBQUAD每个成员存储的内存大小为4字节TRACE("%d %d %d\n", sizeof(BITMAPINFO), sizeof(BITMAPINFOHEADER), sizeof(RGBQUAD));}else if (bmih.biBitCount>=16){dwInfoSize = sizeof(BITMAPINFOHEADER);}else{dwInfoSize = sizeof(BITMAPINFOHEADER) + 4*4*bmih.biClrUsed;//字节对齐,RGBQUAD每个成员存储的内存大小为4字节}dwBitsSize = bmih.biHeight * (((bmih.biBitCount*bmih.biPlanes*bmih.biWidth + 31) & ~31) >> 3);//分配对应的内存区m_pbmi = (PBITMAPINFO)malloc(dwInfoSize);if (NULL == m_pbmi){return FALSE;}m_pBits = (PBYTE)malloc(dwBitsSize);if (NULL == m_pBits){free(m_pbmi);return FALSE;}//读入位图信息和位图数据CopyMemory(m_pbmi, &bmih, sizeof(BITMAPINFOHEADER));if (0 == GetDIBits( pDC->GetSafeHdc(), hExportBmp, 0, bmih.biHeight, m_pBits, m_pbmi, DIB_RGB_COLORS)){free(m_pBits);free(m_pbmi);return FALSE;}/************************************************************************//* 保存数据                                                                     *//************************************************************************///计算文件头信息bmfh.bfType = *(WORD *)"BM";bmfh.bfSize = sizeof(BITMAPFILEHEADER) + dwInfoSize + dwBitsSize;bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + dwInfoSize;//写入到对应BMP文件中HANDLE hFile = CreateFile(  szBmpName,GENERIC_WRITE, 0,NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);CFile m_saveFile(hFile);m_saveFile.Write(&bmfh, sizeof(BITMAPFILEHEADER));m_saveFile.Write(m_pbmi, dwInfoSize);m_saveFile.Write(m_pBits, dwBitsSize);m_saveFile.Close();::DeleteObject(hExportBmp);return TRUE;
}
最新完整截图软件源代码下载链接,这里CScreenBitmap类中是封装好的截图操作,包括屏幕指定区域截图、复制截图到剪切板上及截图保存到磁盘上,你可以在自己的项目中直接使用它。
原创,转载请注明来自http://blog.csdn.net/wenzhou1219

Windows DIB文件操作详解-3.DDB转DIB相关推荐

  1. Windows DIB文件操作详解-4.使用DIB Section

    前面讲了为了提高DIB的显示性能和效率,我们将DIB转换成DDB,但是这又遇到一个问题,如果我想操作DIB的数据的话,显然是不能使用DDB:一是因为DIB转DDB时发生了颜色转换,再就是DDB无法直接 ...

  2. Windows DIB文件操作详解-1.DIB的读入、保存和显示

    DIB(设备无关位图)是存储在磁盘上的位图文件,可以从磁盘读到内存中或从内存保存到磁盘上,它的磁盘文件结构是标准化的,在Linux.Unix及Windows上都可以以同样效果显示.位图是最接近硬件的图 ...

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

    上一节讲到显示DIB的显示时需要将文件内容读到内存中(如下图),当使用SetDIBitsToDevice和StretchDIBits函数显示时中间涉及到一系列的转换,这样大大增加了性能消耗,特别是在重 ...

  4. C 和 C++ 文件操作详解

    来源:http://www.cnblogs.com/likebeta/archive/2012/06/16/2551662.html 来源:http://www.cnblogs.com/likebet ...

  5. Qt QFile文件操作详解

    Qt QFile文件操作详解 很多应用程序都需要具备操作文件的能力,包括对文件内容进行读/写.创建和删除文件等,甚至某些应用程序的诞生纯粹是为了操作文件,比如 WPS Office.PDFedit 等 ...

  6. Python文件操作详解(一)

    今天继续给大家介绍Python相关知识,本文主要内容是Python文件操作详解. 一.Python文件处理简介 使用Python可以编写程序处理文件,Python可以处理的文件值得是任何存储在辅助存储 ...

  7. C++文件操作详解(ifstream、ofstream、fstream)【笔记本】

    C++文件操作详解(ifstream.ofstream.fstream) C++ 通过以下几个类支持文件的输入输出: ofstream: 写操作(输出)的文件类 (由ostream引申而来) ifst ...

  8. 简述python文件操作的流程_Python文件操作详解

    这篇文章主要介绍了Python 文件操作的详解及实例的相关资料,希望通过本文大家能够理解掌握Python 文件操作的知识,需要的朋友可以参考下 Python 文件操作的详解及实例 一.文件操作 1.对 ...

  9. 【Kubernetes 018】cfssl创建证书并结合RBAC的RoleBinding配置新用户config文件操作详解

    安全性是企业生产环境中的头等大事,对于访问同一集群的不同用户或者用户组来说,将权限分级是很有必要的.和很多云厂商一样,k8s也是采用按照角色和用户绑定的方式来分配权限的,这一节我们就来实际操作下,新建 ...

最新文章

  1. 【干货】JMeter BeanShell 应用
  2. Swift之深入解析Key Paths的功能与应用
  3. 用c语言get统计字母个数,请问这个用c怎么做:输入一串字符,分别统计其中数字和字母的个数...
  4. Nginx的server为0.0.0.0/0.0.0.1的作用?
  5. 自动超频_AMD自动超频工具问世:让ZEN2处理器性能上涨、功耗下降
  6. 常用的开始→运行→输入命令集锦
  7. Intel Skylake (Client) 架构/微架构/流水线 (2) - 前端
  8. 【总结】不规则卷积神经网络:可动态提升内核效率
  9. java for循环死循环_Java for循环进化
  10. html5站点是什么意思,html5是什么意思(html5是什么技术)
  11. 云计算里AWS和Azure的探究(3)
  12. 计算机组成原理课设模板,计算机组成原理课程设计报告模板(2011).doc
  13. 如何阅读“三巨人”的源码(1)-比特币
  14. 四元数和旋转_使用OpenCV的四元数
  15. 珠心算 详解(C++)
  16. TCP四次挥手中的2MSL是什么?
  17. 感受Java的魅力——基于Java二维数组和if语句编制的税后工资计算方法
  18. 淘宝购物车计算总价格
  19. java8中新判空方法之Optional类的使用
  20. ESModule 系列 :构建下一代基础设施 PDN

热门文章

  1. PS 第三天学习 如何查看图像及查看图像的高级操作
  2. QWindow类devicePixelRatio函数作用
  3. 操作系统笔记——AD域及桌面策略部署
  4. 原型和原型链原型继承_我如何看待Flash的教训,拥有原型的未来
  5. 自创笔记(全网绝无仅有,持续更新)
  6. 美国服务器对网站SEO优化有哪些影响
  7. 同济大学计算机绩点排名查询,速查!多所院校已公布成绩排名!
  8. 1374 生成每种字符都是奇数个的字符串
  9. patran只显示结点编号
  10. 逻辑思维500题之排除法