当前位置: 首页 > news >正文

C++图像缩放(StretchBlt,StretchDIBits,双线性内插法)

VC++中自带的图像缩放函数两个:

1、

BOOL StretchBlt ( 
int x, 
int y, 
int nWidth, 
int nHeight, 
CDC* pSrcDC, 
int xSrc, 
int ySrc, 
int nSrcWidth, 
int nSrcHeight, 
DWORD dwRop ); 

2、

int StretchDIBits(HDC hdc,                      // handle to DC
  int XDest,                    // x-coord of destination upper-left corner
  int YDest,                    // y-coord of destination upper-left corner
  int nDestWidth,               // width of destination rectangle
  int nDestHeight,              // height of destination rectangle
  int XSrc,                     // x-coord of source upper-left corner
  int YSrc,                     // y-coord of source upper-left corner
  int nSrcWidth,                // width of source rectangle
  int nSrcHeight,               // height of source rectangle
  CONST VOID *lpBits,           // bitmap bits
  CONST BITMAPINFO *lpBitsInfo, // bitmap data
  UINT iUsage,                  // usage options
  DWORD dwRop                   // raster operation code
);
这两个函数的作用是将图像的一部分或全部复制到另一个框架里面去,如果新框架比原来的部分大,则将图像进行放大,否则缩小。(听说这两个函数缩放效果不好,容易引起图像失真)

自己编写图像缩放代码:
 int NewWidth=int(Width*fx+0.5);
int NewHeight=int(Height*fy+0.5);
int NewLineBytes=WIDTHBYTES(NewWidth*8);
HDIB hNewDIB=(HDIB)::GlobalAlloc(GHND,40+4*256+NewLineBytes*NewHeight);//分配句柄空间
if(hNewDIB==NULL) return;
LPBYTE lpDIBnew=(LPBYTE)::GlobalLock((HGLOBAL)hNewDIB);//由新句柄得到第二部分指针
memcpy(lpDIBnew,lpDIB,1064);//复制信息头和调色板
BYTE* lpDIBBitsnew=(BYTE*)(lpDIBnew+40+4*256);//得到第四部分指针
int i0,j0;//图像在原DIB中的坐标
int i,j;//图像在新DIB中的坐标
float m,n;
for(i=0;i<NewHeight;i++)//双线性插值
for(j=0;j<NewWidth;j++)
{
i0=(int)(i/fy+0.5);j0=(int)(j/fx+0.5);//计算该象素在原DIB中的坐标
if((j0>=0)&&(j0<Width)&&(i0>=0)&&(i0<Height))//判断是否在原图像范围内
{
m=(float)(i/fy+0.5)-i0;n=(float)(j/fx+0.5)-(int)j0;
BYTE x1,x2,y1,y2;
x1=*(lpDIBBits+int(LineBytes*(Height-i0-1)+j0));
x2=*(lpDIBBits+int(LineBytes*(Height-i0-1)+j0+1));
y1=*(lpDIBBits+int(LineBytes*(Height-i0)+j0));
y2=*(lpDIBBits+int(LineBytes*(Height-i0)+j0+1));
*(lpDIBBitsnew+NewLineBytes*(NewHeight-i-1)+j)=(BYTE)((1-m)*(1-n)*x1+(1-m)*n*x2+m*(1-n)*y1+m*n*y2);
}
   else 
   *((unsigned char*)(lpDIBBitsnew+NewLineBytes*i+j))=255;//对于原图像中没有的像素,直接赋值为255
}

LPBITMAPINFOHEADER h=(LPBITMAPINFOHEADER)lpDIBnew;//获得指向新图像信息头的指针
h->biHeight=NewHeight;//更新信息头的信息
h->biWidth=NewWidth;
h->biSizeImage=NewWidth*NewHeight;
pDoc->hDib=hNewDIB;
pDoc->dWidth=NewWidth;pDoc->dHeight=NewHeight;
OnInitialUpdate();
Invalidate(TRUE);
delete dlg;

里面用到的是双线性内插法。(比最邻近法好,减少失真)

http://www.xdnf.cn/news/810775.html

相关文章:

  • 软件测试面试及笔试题
  • 【Dom4j】Dom4j完整教程详解
  • 盘点日本人最常用的50个网站
  • tp-link无线网卡linux下的驱动,Ubuntu14下安装无线网卡驱动(TP-LINK TL-WN823N)
  • Visual Studio2010 简体中文含MSDN版本下载地址
  • You-Get 就是这么强势!
  • android的m、mm、mmm编译命令的使用
  • 什么是公网、私网、内网、外网?
  • 使用FileZilla等软件搭建ftp服务器
  • android高级面试题(二)
  • 校园后勤设备保修维护管理系统
  • 递推算法题:令人费解的开关『拉灯』
  • 安卓开发中JDK、SDK、NDK、ADT、ANT等概念作用解释
  • linux命令行怎么结束进程,linux结束进程命令
  • 你必须弄懂的Intent Filter匹配规则
  • C#命令行编辑器csc.exe
  • 基于stm32物联网开发板(3)--SYN6288语音模块
  • 《恐怖丛林生存》肉搏攻略,解开星星系统之谜
  • 电脑提示错误代码0xc000007b该怎么解决,几种解决办法
  • 富贵论坛的来历和背景
  • fast无线路由器设置服务器,迅捷(FAST)FW300R无线路由器怎么设置
  • android开发之PreferenceScreen使用详解
  • 入门级 如何编写第一个网页
  • 理解一般指针和指向指针的指针
  • 黑客的入侵方式你知道几种?
  • cookie是什么?有什么用?cookie详解,一篇文章彻底搞懂cookie
  • Smtp/POP3邮箱服务器地址和端口总结(163/126/QQ)
  • ioctl用法详解
  • html alt 作用,什么是alt标签的作用,alt标签对SEO有哪些影响呢?
  • Jeninkins离线部署