如何将内存中的位图数据绘制在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); |
即可了。
如何将内存中的位图数据绘制在DC上的更多相关文章
- <转>libjpeg解码内存中的jpeg数据
转自http://my.unix-center.net/~Simon_fu/?p=565 熟悉libjpeg的朋友都知道libjpeg是一个开源的库.Linux和Android都是用libjpeg来 ...
- C# 操作地址 从内存中读取写入数据(初级)
本示例以植物大战僵尸为例, 实现功能为 每1秒让阳光刷新为 9999.本示例使用的游戏版本为 [植物大战僵尸2010年度版], 使用的辅助查看内存地址的工具是 CE. 由于每次启动游戏, 游戏中阳光 ...
- 【FFMPEG】从内存中获取H264数据并进行decode
版权声明:本文为博主原创文章,未经博主允许不得转载. 使用ffmpeg解码h264数据其实相对使用x264进行视频编码是简单了许多的,因为ffmpeg提供了一个decoding_encoding.c的 ...
- EXTJS4.2 内存中操作表格数据时,删除表格数据,行号不连续解决
需要重新刷新下表格的view => grid.view.refresh();
- (续)一个demo弄清楚位图在内存中的存储结构
本来续---数字图像处理之位图在计算机中的存储结构一文,通过参考别人的代码,进行修改和测试终于成功运行. 该实例未使用任何API和相关类,相信如果对此实例能够完全理解那么将有进一步进行数字图像处理的能 ...
- C/C++数据在内存中的存储方式
目录 1 内存地址 2 内存空间 在学习C/C++编程语言时,免不了和内存打交道,在计算机中,我们存储有电影,文档,音乐等数据,这些数据在内存中是以什么形式存储的呢?下面做一下简单介绍. 本文是学 ...
- iOS之在内存中绘图
与直接在UIView控件上绘图不同,在内存中绘图时,需要开发者自己准备绘图环境,Quartz 2D提供了一个非常便捷的函数:UIGraphicsBeginImageContext(CGSize siz ...
- C#中使用byte[]数据,生成Bitmap
/// <summary> /// 使用byte[]数据,生成256色灰度 BMP 位图 /// </summary> /// <param name="ori ...
- WPF 自定义的图表(适用大量数据绘制)下
原文:WPF 自定义的图表(适用大量数据绘制)下 上一篇文章中讲了WPF中自定义绘制大量数据的图标,思路是先将其绘制在内存,然后一次性加载到界面,在后续的调试过程中,发现当数据量到达10W时,移动鼠标 ...
随机推荐
- leetcode先刷_Search in Rotated Sorted Array II
上一页下一页,找到相同的旋转阵列的问题.假设数组元素一再怎么办呢?会发生什么? 我给大家举一个极端的例子.如果是这样的阵列中的元件.1,1,2,1,1,1,1,我们想看看这个数组2,刚开始A[midd ...
- Java -- WeakHashMap
一.引言 Java中的引用类型由四种情况,强引用.软引用.弱引用.虚引用.关于这些的介绍可以参见鄙人另外一篇博文. ...
- spring mvc 和ajax异步交互完整实例
Spring MVC 异步交互demo: 1.jsp页面: <%@ page language="java" contentType="text/html; cha ...
- Cannot drop the database ‘XXX’ because it is being used for replication.
删除订阅数据库的时候出现下面的错误: Cannot drop the database ‘XXX’ because it is being used for replication. 数据库的状态为 ...
- Oracle 数据的导入和导出(SID service.msc)
一:版本号说明: (1)(Oracle11 32位系统)Oracle - OraDb11g_home1: (2)成功安装后显演示样例如以下:第一个图是管理工具.创建连接.创建表:第二个是数据库创建工 ...
- Winform ErrorProvider控件使用
要实现的功能:判断第一个文本框中输入的是不是字符 “a”. 最终效果: *当输入的不是a,控件旁会显示错误图标.当输入的是a,则错误图标会消失. 首先添加ErrorProvider控件. 代码: pr ...
- mysql如何开启远程连接
链接地址:http://jingyan.baidu.com/article/046a7b3ed85f3ef9c27fa9dc.html 大家在公司工作中,经常会遇到mysql数据库存储于某个人的电脑上 ...
- getopt、getopt_long和getopt_long_only
GNU/Linux的命令行选项有两种类型:短选项和长选项,前者以 '-' 作为前导符,后者以 '--' 作为前导符.比如有一个命令: $ myprog -a vv --add -b --file a. ...
- JVM调优总结(二)-一些概念
Java对象的大小 基本数据的类型的大小是固定的,这里就不多说了.对于非基本类型的Java对象,其大小就值得商榷. 在Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有 ...
- 如何使用不同dll的相同namespace下的相同接口
问题: 程序里加载了2个dll,这2个dll里都声明了同样的命名空间(这个不违法),然后在这个同样的命名空间下,他俩又定义了同名的interface. 然后我程序里直接using这个命名空间,使用这个 ...