如何将内存中的位图数据绘制在DC上

简介: 假如你定义了一个位图类,里面包含位图头,位图信息头,调色板,位图数据。然后你按照位图的格式将位图文件读入你的类中,现在你知道了位图的全部信息了。主要信息包含在位图信息头里面,数据则在位图数据缓冲里面。现在的问题是,在Windows下面如何将一张位图画出来,而且现在是如何从数据缓存里面绘画出位图。

假如你定义了一个位图类,里面包含位图头,位图信息头,调色板,位图数据。然后你按照位图的格式将位图文件读入你的类中,现在你知道了位图的全部信息了。主要信息包含在位图信息头里面,数据则在位图数据缓冲里面。现在的问题是,在Windows下面如何将一张位图画出来,而且现在是如何从数据缓存里面绘画出位图。
  一般情况,我们都是直接绘制在dc里面,而不是绑定到子控件,让子控件自己绘画,比如picture控件之类的,我觉得提供绘制在dc里面的接口更具有广泛性。

  现在我知道两种从内存数据绘制彩色位图的2种方法。第一种麻烦一点,第二种则相当直接。
  方法一:
  第一步,用CreateCompatibleDC创建跟目标dc的兼容性内存dc。
  第二步,用CreateCompatibleBitmap创建跟目标dc的兼容性位图。
  第三步,用SelectObject将第二步创建的兼容位图选入第一步创建的兼容dc中。
  第四步,用SetDIBits设置兼容位图的数据缓冲
  第五步,用BitBlt将数据从兼容内存dc绘制到目标dc。
  第六步,删除兼容位图和兼容dc。
  代码如下,其中buffer代表位图数据缓冲。

1 HDC hCompatibleDC = CreateCompatibleDC(hDc);
2 HBITMAP hCompatibleBitmap = CreateCompatibleBitmap(hDc, bitmapinfoheader.biWidth,
3 bitmapinfoheader.biHeight);
4 HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCompatibleDC, hCompatibleBitmap);
5 SetDIBits(hDc, hCompatibleBitmap, 0, bitmapinfoheader.biHeight,
6 buffer, (BITMAPINFO*)&bitmapinfoheader, DIB_RGB_COLORS);
7 BitBlt(hDc, nStartX, nStartY, bitmapinfoheader.biWidth, bitmapinfoheader.biHeight,
8 hCompatibleDC, 0, 0, SRCCOPY);
9 SelectObject(hCompatibleDC, hOldBitmap);
10 DeleteObject(hCompatibleDC);
11 DeleteObject(hCompatibleDC);



  方法二:直接调用StretchDIBits绘制位图
  该函数功能相当强悍,似乎专为从内存数据绘制位图到dc而生。
  函数原型如下:
   int StretchDIBits(
   HDC hdc,                      // handle to DC
   int XDest,                    // x-coord of destination upper-left corner
   int YDest,                    // y-coord of destination upper-left corner
   int nDestWidth,               // width of destination rectangle
   int nDestHeight,              // height of destination rectangle
   int XSrc,                     // x-coord of source upper-left corner
   int YSrc,                     // y-coord of source upper-left corner
   int nSrcWidth,                // width of source rectangle
   int nSrcHeight,               // height of source rectangle
   CONST VOID *lpBits,           // bitmap bits
   CONST BITMAPINFO *lpBitsInfo, // bitmap data
   UINT iUsage,                  // usage options
   DWORD dwRop                   // raster operation code
   );
  使用也相当简单,调用

1 StretchDIBits(hDc, nStartX, nStartY, bitmapinfoheader.biWidth,
2 bitmapinfoheader.biHeight, 0, 0, bitmapinfoheader.biWidth,
3 bitmapinfoheader.biHeight, buffer, (BITMAPINFO*)&bitmapinfoheader,
4 DIB_RGB_COLORS, SRCCOPY);

  即可了。

目录
相关文章
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
1022 0
|
缓存 安全 Java
使用 Java 内存模型解决多线程中的数据竞争问题
【10月更文挑战第11天】在 Java 多线程编程中,数据竞争是一个常见问题。通过使用 `synchronized` 关键字、`volatile` 关键字、原子类、显式锁、避免共享可变数据、合理设计数据结构、遵循线程安全原则和使用线程池等方法,可以有效解决数据竞争问题,确保程序的正确性和稳定性。
385 57
|
消息中间件 存储 缓存
kafka 的数据是放在磁盘上还是内存上,为什么速度会快?
Kafka的数据存储机制通过将数据同时写入磁盘和内存,确保高吞吐量与持久性。其日志文件按主题和分区组织,使用预写日志(WAL)保证数据持久性,并借助操作系统的页缓存加速读取。Kafka采用顺序I/O、零拷贝技术和批量处理优化性能,支持分区分段以实现并行处理。示例代码展示了如何使用KafkaProducer发送消息。
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
488 12
|
监控 算法 应用服务中间件
“四两拨千斤” —— 1.2MB 数据如何吃掉 10GB 内存
一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。
336 14
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
1114 1
|
监控 Java easyexcel
面试官:POI大量数据读取内存溢出?如何解决?
【10月更文挑战第14天】 在处理大量数据时,使用Apache POI库读取Excel文件可能会导致内存溢出的问题。这是因为POI在读取Excel文件时,会将整个文档加载到内存中,如果文件过大,就会消耗大量内存。以下是一些解决这一问题的策略:
1991 1
|
存储 编译器
数据在内存中的存储
数据在内存中的存储
198 4
|
存储 机器学习/深度学习 人工智能
数据在内存中的存储
数据在内存中的存储

热门文章

最新文章