C++图像缩放(StretchBlt,StretchDIBits,双线性内插法)
来源:互联网 发布:金融网络销售赚钱吗 编辑:程序博客网 时间:2024/05/17 10:38
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))//判断是否在原图像范围内
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);
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;
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;
里面用到的是双线性内插法。(比最邻近法好,减少失真)
阅读全文
3 0
- C++图像缩放(StretchBlt,StretchDIBits,双线性内插法)
- 图像缩放--双线性内插法
- [图像]图像缩放算法-双线性内插法
- [图像]图像缩放算法-双线性内插法
- 缩放图像的双线性内插法
- 数图的缩放:双线性内插法
- MATLAB实现数图的缩放:双线性内插法
- 图像的近邻、双线性、三次内插法介绍
- 图像处理中两种基本的插值算法(最邻近插值法和双线性内插法)
- 图像处理中两种基本的插值算法(最邻近插值法和双线性内插法)
- StretchBlt与StretchDIBits
- mfc中StretchBlt缩放图像失真问题
- mfc中StretchBlt缩放图像失真问题
- 使用StretchBlt函数进行图像缩放
- 使用StretchBlt函数进行图像缩放
- 使用StretchBlt函数进行图像缩放
- 使用StretchBlt函数进行图像缩放
- 图像缩放双线性插值算法
- Android Studio 构建常见问题汇总
- uinavigationcontroller crash in ios8
- IPC--消息队列
- datastae连接mssql配置
- JSONObject null转为“null”源码解析
- C++图像缩放(StretchBlt,StretchDIBits,双线性内插法)
- 生产者、消费者请求限定 (媒体类型和内容类型解析)
- 《go语言程序设计》第九章练习
- Highcharts中更新series的5种方法
- C++搜索与回溯算法之母亲的牛奶
- iOS-延时/定时总结(OC)
- Android动画总结系列(1)——帧动画
- C++primer charpter 4笔记(一)
- SOAP webserivce 和 RESTful webservice 对比及区别