- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
5.5 用VC编程实现BMP图像裁切
随着计算电子技术和计算机技术的发展,数字图像处理进入高速发展时期,许多成熟的图像处理软件如雨后春笋般层出不穷。在大多数图像处理软件中都有图像裁切功能,用它能够快速提取感兴趣区域,去掉多余的图像内容。那么怎样编程实现图像裁切呢,下面以BMP图像为例介绍一下如何用VC实现图像裁切。
先介绍第一种方法,将图像数据全部读入内存,然后将感兴趣区域裁切下来。在许多数字图像处理的书中都有关于BMP图像存储结构的章节,这里就不再详细介绍了。BMP文件一般分为四个部分:位图头文件、位图信息头、调色板和图像数据。图像裁切要用到位图信息头中的几个参数值:biWidth(图像宽度)、biHeight(图像高度)、biBitCount(每个像素的位数)、biSizeImage(图像长度)。图像裁切首先要确定裁切区域内每个像素在整幅图像中的位置,我们以裁切区域中心点像素位置起算,要注意的是图像数据的存储是从最下面一行的左边开始的。如下图,Height是图像高,Width是图像宽,ctPoint是裁切区域中心点坐标,dwX和dwY分别是裁切区域的宽和高。以256色图像为例(每个像素占一个字节),裁切区域左下角像素(也就是裁切后图像的第一个像素)位置为(Height-ctPoint.y-dwY/2-1)×Width+ctPoint.x-dwX/2,左下角像素位置确定了,裁切区域内的其他像素位置就很容易确定。确定了裁切区域内每个像素的位置后,就可以把这些像素的值赋给裁切后图像的相应像素。裁切后图像的位图信息头和调色板只要从原图像数据中拷贝就可以了,修改信息头中图像宽、高和长度值为裁切后的值。
按照上面的思路笔者用VC++ 6.0编写了一个图像裁切函数ClipDIB(),该函数首先计算裁切区域图像数据的大小,为裁切后的图像分配内存,然后将原图像的信息头、调色板拷贝给裁切后的图像,最后将原图像中裁切区域内的像素值赋给裁切后影像。
HDIB CBMP_ViewView::ClipDIB(HDIB hDib,CPoint ctpoint,DWORD dwX,DWORD dwY)
{
// 假如图像为空则返回
if (hDib == NULL)
{
return NULL ;
}
// 获得图像指针
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDib);
// 图像信息头指针
LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) lpDIB ;
// 如果裁切中心点超出图像范围
if (ctpoint.x (int)DIBWidth(lpDIB)||ctpoint.y (int)DIBHeight(lpDIB))
{
AfxMessageBox(中心点不在图像范围内) ;
return NULL ;
}
DWORD dwxSave ; // 实际影像保存的宽度
DWORD dwBitsSize ; // 裁切后图像区域大小
if ((int(ctpoint.x - dwX/2)0)(int(ctpoint.y - dwY/2)0)
(ctpoint.x + dwX/2)DIBWidth(lpDIB)(ctpoint.y + dwY/2)DIBHeight(lpDIB))
{
AfxMessageBox(裁切区域超出图像范围) ;
return NULL ;
}
// 实际影像保存的宽度为4字节的整数倍
dwxSave = (dwX * lpBMIH-biBitCount + 31)/32 * 4 ;
// 实际影像块的大小
dwBitsSize = dwxSave * dwY ;
// 裁切后的DIB图像大小(不包含文件头)
DWORD dwClipedSize ;
dwClipedSize = sizeof(BITMAPINFOHEADER) + PaletteSize(lpDIB) + dwBitsSize ;
// 为裁切后的DIB分配内存
HDIB hClipedDIB ;
文档评论(0)