VC中挑选BMP图片的矩形区域子集

现在有一个BMP图片, 要挑选出它的一块矩形区域子图片。如下图所示,左边为原来的BMP图片,右边为通过鼠标挑选出来的子图片。

我是通过读取BMP本身的数据DATA,然后只拷贝矩形区域的DATA到一个新的buffer中来实现的,没有调用函数库。




void CpictureControlDlg::GetBMPSubImage(BITMAPINFOHEADER *pParentHead, BYTE *pParentBits, const CRect &subArea,
	BITMAPINFOHEADER *&pSubHead, BYTE *&pSubBits)
{
	if ((pParentHead == nullptr) 
		|| (pParentBits == nullptr))
	{
		return;
	}

	if (pSubHead != nullptr)
	{
		delete pSubHead;
	}
	if (pSubBits != nullptr)
	{
		delete []pSubBits;
	}

	pSubHead = new BITMAPINFOHEADER;
	memcpy(pSubHead, pParentHead, sizeof(BITMAPINFOHEADER));
	pSubHead->biWidth = abs(subArea.Width());
	pSubHead->biHeight = abs(subArea.Height());

	
	const int subOneLineBytes = subArea.Width() * pSubHead->biBitCount / 8;
	const int subOneLineAlignBytes = (subOneLineBytes % 4 == 0) ? subOneLineBytes : (subOneLineBytes / 4 + 1) * 4;
	int subImageDataSize = subOneLineAlignBytes * pSubHead->biHeight;
	pSubBits = new BYTE[subImageDataSize];
	pSubHead->biSizeImage = subImageDataSize;
	memset(pSubBits, 0, subImageDataSize);
	BYTE *p = pSubBits;
	const int lineOffset = subArea.left * pSubHead->biBitCount / 8;
	const int parentOneLineBytes = pParentHead->biWidth * pParentHead->biBitCount / 8;
	for (int line = pParentHead->biHeight - subArea.bottom; line < pParentHead->biHeight - subArea.top; ++line)
	{
		memcpy(p, pParentBits + line*parentOneLineBytes + lineOffset, subOneLineBytes);
		p += subOneLineAlignBytes;
	}
}
 上述代码说明,这个函数一共5个参数, 其中前两个参数,用来描述原始BMP图片,中间的CRect用来描述子图在原始图片中对应的矩形区域,

最后两个参数作为输出,用来描述子图片。


完成上述代码要注意两点:

1. 位置描述不一致。 CRect的坐标系使用的是屏幕坐标系, 原点位于左上角,x轴向右,Y轴向下。 

而bmp图片数据,即代码中的pBits的存储的原点位于图片左下角,x轴向右,y轴向上。

2. 选择出来的子bmp图片需要进行4字节对齐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值