MFC还原rgb565位图数据为图片

版权声明:本文为博主原创文章,转载申明

最近几天做了一个还原串口传输的rgb565数据为图片的上位机,

中间过程遇到最大的困难便是不知道如何去正确的写入位图数据。

因为过去都是直接还原灰度图,没有涉及过还原彩色图片,所以一开始的时候遇到过很多的不解,

简单的认为rgb565的位图数据大小只是图片的长X宽,到后来了解到串口最长只能发送8个bit,

而同样以BYTE型数组存储的rgb565的位图数据正好也是8位,

所以正确的16位的rgb565位图数据大小应该是长X宽X2;

这也符合了bmp文件格式中所规定的位图数据大小:BPP * Width * Height/8(BPP是每像素的比特数(Bits Per Pixel),即biBitCount,Width是宽度,Height是高度)。当初没有看到这一点瞎忙活了半天。。。

之后便是关于如何添加文件头和位图信息头,因为是16位的真彩图,不需要去添加调色板所以只需要正确设置文件头和位图信息头即可,

而MFC最为方便的一点便是提供了一个CImage::CImage的 构造函数;我们只需要去创建一个

	CImage m_COMImage;

就可以去接受位图数据啦,前提是你要设置好前面所提到的文件头和位图信息头(搞来搞去还是要设置。。。)

但是,重点来了,

这个设置只需要一句代码

	//初始化image
	DWORD adwBitmasks[3] = { 0x0000F800, 0x000007E0, 0x0000001F };		//设置掩码
	image.CreateEx(width, height, 16, BI_BITFIELDS, adwBitmasks, 0);	//宽度高度和位数

差不多一句。。。

下面是vs2015c++的官方文档对CreateEx这个函数的解释:

BOOL CreateEx(
	int nWidth,
	int nHeight,
	int nBPP,
	DWORD eCompression,
	const DWORD* pdwBitmasks = NULL,
	DWORD dwFlags = 0 
) throw( );

nWidth
CImage 位图的宽度,以像素为单位。

nHeight
CImage 位图的高度,均以像素。 如果 nHeight 为正数的,位图是一个从下到上DIB,并且原点是左下角。 如果 nHeight 为负,位图是一组DIB,并且原点为左上角。

nBPP
位的数目每在位图的像素。 通常4,8,16,24或32。 可以是1单色位图或掩码。

eCompression
为压缩的位图指定压缩的类型(自下而上的 DIB 不能压缩)。 可为下列值之一:
BI_RGB 该格式被解压缩。 指定此值,在调用 CImage::CreateEx 时与调用 CImage::Create等效。
BI_BITFIELDS布局是解压缩,而且颜色表包含指定红色,绿色和蓝色分量,分别,每个像素的三 DWORD 颜色掩码。 这是有效的,但在用于16位和32-bpp位图。

初始化完成后就需要写入位图数据了,主要是利用两个嵌套for循环去一行一行写入位图数据。

在写入数据的时候要格外的小心,注意你当初设置的高度是正数还是负数,因为这个关系到写入位图数据的起点,不然很可能在写入位图数据时造成数组的越界。

也可以通过CImage::GetPitch先去读取图像的间距,确定写入位图数据的起点,

下面是vs2015c++的官方文档对GetPitch这个函数的解释:

返回值

图像的间距。 如果返回值为负,位图是一个从下到上DIB,并且原点是左下角。 如果返回值为正的,位图是一组DIB,并且原点为左上角。

备注

间距是距离,在字节,在表示一个位图行开头和位图下一行的开头的两个内存地址之间。 由于间距以字节为单位,图像帮助的间距确定像素格式的。 间距还可以包括附加的内存,预留位图。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值