GDI -- 将灰度图数据画到控件上

实现功能

  1. 将灰度图内存数据画到控件上
  2. 原始灰度图的宽高与控件宽高不相同
  3. 在画到控件上之前要在原始的灰度图上做一些效果,如叠加文字、画效果图形等

上代码

void ShowFrameOnCtl(HWND hWnd, unsigned char* frame, int w, int h)
{
	HDC hdcPicControl;

	// GetDC() need to be ReleaseDC
	hdcPicControl = ::GetDC(hWnd);

	RECT rcPic;
	::GetClientRect(hWnd, &rcPic);

	int nWidth = rcPic.right - rcPic.left;
	int nHeight = rcPic.bottom - rcPic.top;

	HDC hCompatibleDC = CreateCompatibleDC(hdcPicControl);
	HBITMAP hCompatibleBitmap = CreateCompatibleBitmap(hdcPicControl, w, h);
	HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCompatibleDC, hCompatibleBitmap);

	// 灰度图
	BITMAPINFOHEADER BitmapInfo;
	BITMAPINFO *_BitmapInfo = (BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER) * 256 * sizeof(RGBQUAD)];
	memset(_BitmapInfo, 0, sizeof(BITMAPINFOHEADER));

	BitmapInfo.biSize = 40;
	BitmapInfo.biPlanes = 1;
	BitmapInfo.biBitCount = 8;
	BitmapInfo.biClrImportant = 0;
	BitmapInfo.biCompression = BI_RGB;
	BitmapInfo.biXPelsPerMeter = 0;
	BitmapInfo.biYPelsPerMeter = 0;
	BitmapInfo.biClrUsed = 256;
	BitmapInfo.biClrImportant = 0;
	BitmapInfo.biWidth = 0;
	BitmapInfo.biHeight = 0;

	/*把BMP位图信息头中的数据读取到位图信息结构中去.*/
	memcpy(_BitmapInfo, &BitmapInfo, sizeof(BITMAPINFOHEADER));

	RGBQUAD *rgb = (RGBQUAD*)((BYTE*)_BitmapInfo + sizeof(BITMAPINFOHEADER));
	for (int i = 0; i < 256; ++i) {
		rgb[i].rgbBlue = rgb[i].rgbGreen = rgb[i].rgbRed = i;
	}

	_BitmapInfo->bmiHeader.biWidth = w;
	_BitmapInfo->bmiHeader.biHeight = -1 * h;
	_BitmapInfo->bmiHeader.biSizeImage = 0;
	_BitmapInfo->bmiHeader.biBitCount = 8;
	_BitmapInfo->bmiHeader.biClrUsed = 256;

	SetStretchBltMode(hCompatibleDC, COLORONCOLOR);
	StretchDIBits(hCompatibleDC,
		0, 0, w, h,
		0, 0, w, h,
		frame, _BitmapInfo, DIB_RGB_COLORS, SRCCOPY);

	//在内存DC上画一些效果
	if (!m_disableDraw)
		drawView(hCompatibleDC, w, h);

	delete _BitmapInfo;

	SetStretchBltMode(hdcPicControl, COLORONCOLOR);
	::StretchBlt(hdcPicControl, 0, 0, nWidth, nHeight, hCompatibleDC, 0, 0, w, h, SRCCOPY);

	SelectObject(hCompatibleDC, hOldBitmap);
	DeleteObject(hCompatibleBitmap);
	DeleteDC(hCompatibleDC);
	// ReleaseDC of hdcPicControl
	ReleaseDC(hWnd, hdcPicControl);
}

小结

创建内存位图
HBITMAP CreateCompatibleBitmap(HDC hdc,int nWidth,int nHeight)

nWidth 和 nHeight不一定要和hdc的大小一样, 这样可以让创建的位置和原始图像一致,最后内存DC拷贝到原始DC时,缩放一下即可

背景知识

什么是DC

device context is a structure that defines a set of graphic objects and their associated attributes, as well as the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations. The remainder of this section is divided into the following three areas.

这是微软官方的解释,翻译一下:

DC全称Device Contexts, 意为设备上下文,它是一个定义了一系列图形对象及其属性发生的数据结构,其他也包括一些影响显示的图形模式。 图形对象包括画笔(画直线)、画刷(填充)、位图(拷贝或滚动屏幕的其他部分)、调色板(定义了一系列颜色)、裁剪区、路径。

另外,设备上下文是设备无关的,DC主要是给用户一致的绘图体验,它是用户与真实设备驱动之间一个桥梁,用来屏蔽设备驱动等底层细节

双缓冲

双缓冲是一种方法,它可以用来避免画图闪烁的问题。如果直接在画布上画图,每次都要先擦除再绘制,这一过程需要时间,如果显示的刷新频率很快或绘制过程很慢(比较CPU性能差),就会让用户看到这一中间过程,造成闪烁现象。

Win32中双缓冲的原理是先创建一个内存DC,画图绘制在内存DC上,绘制好后将内存DC直接拷贝到原始DC上,这样就避免了闪烁。


就酱~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一马途追

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值