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

假如你定义了一个位图类,里面包含位图头,位图信息头,调色板,位图数据。然后你按照位图的格式将位图文件读入你的类中,现在你知道了位图的全部信息了。主要信息包含在位图信息头里面,数据则在位图数据缓冲里面。现在的问题是,在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);

  即可了。

时间: 2024-11-17 13:53:10

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

迭代-从数据库中获取的数据在jsp页面上的显示问题

问题描述 从数据库中获取的数据在jsp页面上的显示问题 做一个项目的时候,从数据库获取数据,用迭代的方式在前台显示,只能显示一部分的信息,就好像是有一个固定空间似的,只要内容超出了这个空间,就不能显示了,怎么解决? 代码如下: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri=&

visual studio中如何把内存中的一组数据用图形画出来

问题描述 求助大家指点!我在内存中建立了一个数组,是一个正弦信号的采样点,我现在想把这组数据按照从第一个到最后一个在XY坐标平面上画出来,看看是不是真的是正弦形状,有什么解决办法呢?谢谢! 解决方案 解决方案二:如果想简单,用chart控件如果不想用控件,自己GDI+画,然后放到picturebox里,或panel上显示,或将图片另存为文件都行解决方案三:用chart控件吧,可以直接绑定数组画出来

如何让你的内存中的 NoSQL 数据存储适合企业级应用

对于关注用户体验的每一个Web或移动应用而言,基于内存的NoSQL数据存储系统(例如开源的 Redis和Memcached)正在成为事实标准.由于性能.可扩展性和可用性面临的诸多挑战,很多大企业已经在试图采用这些数据库系统. 非常幸运的是,现代编程语言(例如Ruby.Node.js.Python等)和开发平台(例如Rails.Sinatra.Django等)已经内置了很多工具和开发库(libraries).这些工具和开发库能够有效利用内存数据库的高性能和各种操作命令,能够实现当前流行的多种应用项

C#中使用byte[]数据,生成Bitmap

/// <summary> /// 使用byte[]数据,生成256色灰度 BMP 位图 /// </summary> /// <param name="originalImageData"></param> /// <param name="originalWidth"></param> /// <param name="originalHeight"><

Android手机内存中文件的读写方法小结

  Android手机内存中文件的读写方法小结         这篇文章主要介绍了Android手机内存中文件的读写方法,实例总结了Android针对文件读写操作的相关技巧,非常具有实用价值,需要的朋友可以参考: 如何对手机内存中的文件数据进行读写呢? Context提供了领个方法来打开该应用程序的数据文件夹中的文件I/O流,具体如下: ? 1 FileInputStream openFileInput(String name) 打开应用程序的数据文件夹下的name文件对应的数据流 ? 1 Fi

修改内存-汇编中使用debug更改内存中的内容问题

问题描述 汇编中使用debug更改内存中的内容问题 为了学习汇编,我经常使用debug中的指令修改主板内存中存的数据,我想问的是,我这样总是修改联系的话会不会使电脑内存出现问题呢?有牛人说虽然我们经常修改的是那些可以修改的内存内容,但是有的机器甚至连主板ROOM内容都能修改,这样练习练习岂不是我们很有可能将来得换一块主板?哈哈,不知道我说的哪里有问题,请大神指教!谢谢 我是在虚拟机中安装操作系统,在用debug修改内存内容的,也不知道这样做是不是会影响虚拟机中的系统的正常性能,反正是不会影响原本

配置内存中OLTP文件组提高性能

原文:配置内存中OLTP文件组提高性能 在今天的文章里,我想谈下使用内存中OLTP的内存优化文件组来获得持久性,还有如何配置它来获得高性能.在进入正题前,我想简单介绍下使用你数据库里这个特定文件组,内存OLTP是如何获得持久性的. 内存中OLTP的持久性 早些天对内存中OLTP(代号Hekaton)的一个大误解是,人们认为内存中OLTP是不具有ACID属性的--只有ACI属性,没有D属性(Durability).但这不是真的,因为在内存中OLTP里,每个在内存中的操作都是完全日志的.如果你的数据

打算做个在线客服系统,有关在内存中保存离线DataTable的问题

问题描述 打算给自己开发中的在线订餐系统做一个在线客服,用SessionId跟商家的ID区分,采用Ajax,定时刷新,觉得如果把聊天的记录存储在SQL数据里,那么如果对话的客户多了的话,定时刷新,每次都要读取一次数据库,对数据库的负荷很大.因为商家的数量有限,所以打算用内存中的DataTable来保存各个商家聊天记录,定时或者检测到内存中DataTable的数据资料到了一定数量(比如记录超过100条,那么就把前80条存到SQL数据库里),因为每次直接从内存读取数据,不经过数据库,这样应该能减少很

动态获得记录信息,然后先将获得的记录信息保存在一个列表(内存中),再定义一个定时器,定期将列表中的记录(批量)写入数据库

问题描述 windFrom当点击添加学生信息时,是先将学生记录保存在一个列表(内存中),定义一个定时器,定期将列表中的学生记录(批量)写入数据库如何做?高手请进,谢谢.//学生信息实体.cspublicclassstuInfo{publicstringname;//学生性名publicstringsex;//学生性别publicstringinfo;//备注信息}//DAO操作.cspublicclassDAO_stuInfo{privateDataBasedb;publicDAO_stuInf