将数组中的RGBA序列绘制出来——GDI、MFC_GDI、GDI+实现
2013-12-10 13:03
190 查看
如果你有一个字节数组,里面存放着R/G/B/A颜色值序列,如何将它所表示的图片绘制在窗口上呢?
之前在论坛上看到有人提了这么一个问题:http://bbs.csdn.net/topics/390663627
这个用GDI、MFC封装的GDI、GDI+均可实现。不过要注意的是内存中的R、G、B、A顺序得调整下,调整为B、G、R、A。因为这是windowsGDI内部使用的顺序。
还有,GDI不支持透明通道A,透明通道A的值读进去以后不起作用。
欲支持透明通道,应使用GDI+实现。
GDI实现:
MFC封装的GDI实现:
GDI+实现:
这些只是个简单的例子,没有做错误处理,在实际使用时注意错误处理。
可见MFC对GDI的封装,并没有使我们的开发变的更简单。
不过值得注意的是两个需要释放内存的地方,由对象的析构函数帮我们完成了,减少了因疏忽而带来的内存泄露、GDI对象泄露问题的发生率。
而GDI+更加面向对象,代码编更简单,并且内存释放、GDI对象释放大多由它负责,进一步减少了因程序员疏忽而带来的内存泄露、GDI对象泄露问题的发生率。
使用上述GDI+代码,在一个循环中不断递增透明通道值并绘制的效果:
MSDN上的GDI+文档:http://msdn.microsoft.com/en-us/library/windows/desktop/ms533799(v=vs.85).aspx
之前在论坛上看到有人提了这么一个问题:http://bbs.csdn.net/topics/390663627
这个用GDI、MFC封装的GDI、GDI+均可实现。不过要注意的是内存中的R、G、B、A顺序得调整下,调整为B、G、R、A。因为这是windowsGDI内部使用的顺序。
还有,GDI不支持透明通道A,透明通道A的值读进去以后不起作用。
欲支持透明通道,应使用GDI+实现。
GDI实现:
//参数2、3:图片绘制在目标窗口上的位置,即图片左上角在窗口上的坐标,比如(0,0) void DrawBitmap(HWND hwnd, int x, int y, int nBmpWidth, int nBmpHeight,const unsigned char *pBmpData) { HBITMAP hBitmap = ::CreateBitmap(nBmpWidth, nBmpHeight, 1, 32, pBmpData); HDC hWndDc = ::GetDC(hwnd); HDC hMemDc = ::CreateCompatibleDC(hWndDc); HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemDc, hBitmap); ::BitBlt(hWndDc, x, y, nBmpWidth, nBmpHeight, hMemDc, 0, 0, SRCCOPY); ::SelectObject(hMemDc, hOldBitmap); ::DeleteObject(hBitmap); ::DeleteDC(hMemDc); ::ReleaseDC(hwnd, hWndDc); }
MFC封装的GDI实现:
//参数2、3:图片绘制在目标窗口上的位置,即图片左上角在窗口上的坐标,比如(0,0) void DrawBitmap(CWnd *pWnd, int x, int y, int nBmpWidth, int nBmpHeight,const unsigned char *pBmpData) { CBitmap bitmap;CDC MemDc; bitmap.CreateBitmap(nBmpWidth, nBmpHeight, 1, 32, pBmpData); CDC *pWndDc = pWnd->GetDC(); MemDc.CreateCompatibleDC(pWndDc); CBitmap *pOldBitmap = MemDc.SelectObject(&bitmap); pWndDc->BitBlt(x, y, nBmpWidth, nBmpHeight, &MemDc, 0, 0, SRCCOPY); MemDc.SelectObject(pOldBitmap); pWnd->ReleaseDC(pWndDc);pWndDc = NULL; }
GDI+实现:
#include <GdiPlus.h> #pragma comment(lib,"Gdiplus.lib") using namespace Gdiplus; //该类主要用来在程序启动时自动执行GdiplusStartup,程序结束时执行GdiplusShutdown //使得GDI+可以正常工作,也可以不定义该类,而在自己的代码中自行调用GdiplusStartup和GdiplusShutdown class GdiPlusInit { GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiPlusInit() { GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); } ~GdiPlusInit() { GdiplusShutdown(gdiplusToken); } static GdiPlusInit Instance; }; GdiPlusInit GdiPlusInit::Instance; //参数2、3:图片绘制在目标窗口上的位置,即图片左上角在窗口上的坐标,比如(0,0) void DrawBitmap(HWND hwnd, int x, int y, int nBmpWidth, int nBmpHeight,unsigned char *pBmpData) { Bitmap bitmap(nBmpWidth, nBmpHeight, nBmpWidth * 4, PixelFormat32bppARGB, pBmpData); Graphics gps(hwnd); gps.DrawImage(&bitmap, x, y); }
这些只是个简单的例子,没有做错误处理,在实际使用时注意错误处理。
可见MFC对GDI的封装,并没有使我们的开发变的更简单。
不过值得注意的是两个需要释放内存的地方,由对象的析构函数帮我们完成了,减少了因疏忽而带来的内存泄露、GDI对象泄露问题的发生率。
而GDI+更加面向对象,代码编更简单,并且内存释放、GDI对象释放大多由它负责,进一步减少了因程序员疏忽而带来的内存泄露、GDI对象泄露问题的发生率。
使用上述GDI+代码,在一个循环中不断递增透明通道值并绘制的效果:
MSDN上的GDI+文档:http://msdn.microsoft.com/en-us/library/windows/desktop/ms533799(v=vs.85).aspx
相关文章推荐
- GDI+绘制矩形,并且实现可旋转、缩放、移动功能(基于MFC对话框)
- MFC之GDI GDI+ 一键绘制正弦曲线图
- MFC GDI 曲线图绘制
- 判断数组是否是二叉搜索树的后序遍历序列 JAVA实现
- 用GDI+怎么实现绘制倾斜文字
- MFC之GDI GDI+ 编程实例剖析
- 经典面试题:求数组的最大子序列和;实现函数 :判断一个自负喜欢是否是另一个字符串旋转所得;杨氏矩阵中查找一个数。
- MFC界面编程1:GDI+实现不规则窗体
- Windows编程 GDI简单图形的绘制 简单实现锁帧效果
- 求一个数组的最长的单调自增子序列(C代码实现)
- C#把数组中的某个元素取出来放到第一个位置的实现方法
- 原生js实现ajax和将数组以列表形式显示出来
- 2015-4-2的阿里巴巴笔试题:乱序的序列保序输出(bit数组实现hash)
- JavaScript实现找出数组中最长的连续数字序列
- 如何基于纯GDI实现alpha通道的矢量和文字绘制
- MFC 使用GDI+ 绘制Png、Jpg等类型图片
- OpenGL 通过VBO实现顶点数组绘制顶点
- MFC & Gdi+ 实现在图片上写中文 (OpenCV原生不支持写中文本到图片,当然FreeType库也可实现)
- MFC使用API函数GdiAlphaBlend绘制半透明控件
- MFC GDI+实现以鼠标为中心缩放图片(并且可以拖动)