上篇写读取BMP文件并在界面DC上显示了,是经过拉伸的
现在呢,在DC上画个矩形框框,从内存图像数据中,截取矩形框框的图像数据
画框框这部分跳过,需要知道你在DC区域的起点坐标和终点坐标,还有DC区域的宽高,还要有原图的图像数据Buf和头信息
- void CBMPControl::CutBMP(CPoint OrgPoint,CPoint EndPoint,int ircWidth,int ircHeight)//从内存中截图
- {
- //先根据宽高进行比例计算
- float fWidthScale = (float)ircWidth/BmpInfo.bmiHeader.biWidth;//宽的比例
- float fHeightScale = (float)ircHeight/BmpInfo.bmiHeader.biHeight;//高的比例
- int iOrgX = OrgPoint.x/fWidthScale+0.5;//进行四舍五入
- int iOrgY = OrgPoint.y/fHeightScale+0.5;
- int iEndX = EndPoint.x/fWidthScale+0.5;
- int iEndY = EndPoint.y/fHeightScale+0.5;
- long lWidth = iEndX - iOrgX;//截图的像宽
- long lHeight = iEndY - iOrgY;//高度
- long lLineSize = (lWidth*BmpInfo.bmiHeader.biBitCount+31)/32*4;//截图一行字节数
- long lImgSize = lLineSize*lHeight;//截图总大小
- pCutBMPBuf = new BYTE[lImgSize];//分配内存
- memset(pCutBMPBuf,0,lImgSize);
- BYTE * pSBuf = NULL;//指向源图数据指针
- BYTE * pDBuf = NULL;//指向pCutBMPBuf的指针
- pDBuf = pCutBMPBuf;
- //在内存中,存储方式是倒置的,内存第一行第一个,是显示的最后一行第一个,x不变,y倒置
- long lSrcLineSize = (BmpInfo.bmiHeader.biWidth*BmpInfo.bmiHeader.biBitCount+31)/32*4;//原图一行数据大小
void CBMPControl::CutBMP(CPoint OrgPoint,CPoint EndPoint,int ircWidth,int ircHeight)//从内存中截图
{
//先根据宽高进行比例计算
float fWidthScale = (float)ircWidth/BmpInfo.bmiHeader.biWidth;//宽的比例
float fHeightScale = (float)ircHeight/BmpInfo.bmiHeader.biHeight;//高的比例
int iOrgX = OrgPoint.x/fWidthScale+0.5;//进行四舍五入
int iOrgY = OrgPoint.y/fHeightScale+0.5;
int iEndX = EndPoint.x/fWidthScale+0.5;
int iEndY = EndPoint.y/fHeightScale+0.5;
long lWidth = iEndX - iOrgX;//截图的像宽
long lHeight = iEndY - iOrgY;//高度
long lLineSize = (lWidth*BmpInfo.bmiHeader.biBitCount+31)/32*4;//截图一行字节数
long lImgSize = lLineSize*lHeight;//截图总大小
pCutBMPBuf = new BYTE[lImgSize];//分配内存
memset(pCutBMPBuf,0,lImgSize);
BYTE * pSBuf = NULL;//指向源图数据指针
BYTE * pDBuf = NULL;//指向pCutBMPBuf的指针
pDBuf = pCutBMPBuf;
//在内存中,存储方式是倒置的,内存第一行第一个,是显示的最后一行第一个,x不变,y倒置
long lSrcLineSize = (BmpInfo.bmiHeader.biWidth*BmpInfo.bmiHeader.biBitCount+31)/32*4;//原图一行数据大小
- <SPAN style="WHITE-SPACE: pre"> </SPAN>//BmpInfo是原图的信息结构,pBMPDataBuf是原图的数据buf
//BmpInfo是原图的信息结构,pBMPDataBuf是原图的数据buf
- <SPAN style="WHITE-SPACE: pre"> </SPAN>//先把指针移动到最后一行的第一个像素字节
- pSBuf = pBMPDataBuf+(BmpInfo.bmiHeader.biHeight-iEndY)*lSrcLineSize+//原图一行的字节大小*截图的最后一行的位置+第一个像素的字节位置
- (iOrgX*BmpInfo.bmiHeader.biBitCount+31)/32*4;//第一个像素位置就是起点的X,转换为字节位置
- for(int i = 1;i<=lHeight;i++)
- {
- memcpy(pDBuf,pSBuf,lLineSize);//从源图中拷贝lLineSize个数据到目标内存
- pSBuf = pBMPDataBuf+(BmpInfo.bmiHeader.biHeight-(iEndY-i))*lSrcLineSize+//一行一行的拷贝数据
- (iOrgX*BmpInfo.bmiHeader.biBitCount+31)/32*4;
- if (i!=lHeight)//没有到最后一行,就继续移动
- {
- pDBuf = pDBuf + lLineSize;//往后移动等待拷贝
- }
- }
//先把指针移动到最后一行的第一个像素字节
pSBuf = pBMPDataBuf+(BmpInfo.bmiHeader.biHeight-iEndY)*lSrcLineSize+//原图一行的字节大小*截图的最后一行的位置+第一个像素的字节位置
(iOrgX*BmpInfo.bmiHeader.biBitCount+31)/32*4;//第一个像素位置就是起点的X,转换为字节位置
for(int i = 1;i<=lHeight;i++)
{
memcpy(pDBuf,pSBuf,lLineSize);//从源图中拷贝lLineSize个数据到目标内存
pSBuf = pBMPDataBuf+(BmpInfo.bmiHeader.biHeight-(iEndY-i))*lSrcLineSize+//一行一行的拷贝数据
(iOrgX*BmpInfo.bmiHeader.biBitCount+31)/32*4;
if (i!=lHeight)//没有到最后一行,就继续移动
{
pDBuf = pDBuf + lLineSize;//往后移动等待拷贝
}
}
- }
}
这样获得了截图的数据,自己再构造bmp文件头,或者用原图的也可以,该下数据大小和宽高,就可以保存图片了
显示效果图,上面为原图画矩形框,下面为截取的图

BMP图像截取技巧
本文详细介绍了一种从已加载的BMP图像中截取指定区域图像数据的方法,并提供了具体的C++实现代码。通过比例计算确定截取范围,正确处理图像数据的存储顺序,实现了高效准确的图像截取。
7464

被折叠的 条评论
为什么被折叠?



