将数组中的RGBA序列绘制出来——GDI、MFC_GDI、GDI+实现

如果你有一个字节数组,里面存放着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实现:

//参数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

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值