今天将图像缩放的双线性内插法弄完了,主要的思想如下:
对于一个目的像素,通过目标图像与源图像的比值进行反向变换得到一个浮点坐标,如fx(x+u,y+v)其中为非负整数,u,v为区间[0,1]上的浮点数。则目的像素的颜色值可以由源图像的点fx(x,y)与其相邻的四个点的颜色值决定。
公式为:fx(x+u,y+v)=(1-u)(1-v)fx(x,y)+(1-u)(v)fx(x,y+1) +(u)(1-v)fx(x+1,y)+uvfx(x+1,y+1);
下面是我自己写的一个缩放图像的函数。
void CTestView::Linear_BMP(COLORREF **DesImage,double DesWidth,double DesHeight,COLORREF **SrcImage ,double SrcWidth,double SrcHeight) { if(SrcImage == NULL) return; DesImage=new COLORREF*[(int)DesHeight]; for(int n1=0;n1<DesHeight;n1++) DesImage[n1]=new COLORREF[(int)DesWidth]; double w = (double)SrcWidth/(double)DesWidth;//源/目标=比例 double h = (double)SrcHeight/(double)DesHeight; double u,v; double Sx,Sy; double pm[4]; int tx,ty; int red[4],green[4],blue[4]; double r=0,g=0,b=0; for(int i = 0; i < DesHeight; i++) { Sy = (double)(i) * h; ty = (int)Sy; v = fabs(Sy - ty); for(int j = 0; j<DesWidth; j++) { Sx = (double)(j) * w ; tx = (int)Sx; u = fabs(Sx - tx); pm[0] = ( 1.0 - u ) * ( 1.0 - v ); pm[1] = v * ( 1.0 - u ); pm[2] = u * ( 1.0 - v ); pm[3] = u * v; if(tx>=SrcWidth - 2) tx = SrcWidth - 2; if(ty>=SrcHeight - 2) ty = SrcHeight - 2; red[0] = GetRValue(SrcImage[ty][tx]); red[1] = GetRValue(SrcImage[ty+1][tx]); red[2] = GetRValue(SrcImage[ty][tx+1]); red[3] = GetRValue(SrcImage[ty+1][tx+1]); green[0] = GetGValue(SrcImage[ty][tx]); green[1] = GetGValue(SrcImage[ty+1][tx]); green[2] = GetGValue(SrcImage[ty][tx+1]); green[3] = GetGValue(SrcImage[ty+1][tx+1]); blue[0] = GetBValue(SrcImage[ty][tx]); blue[1] = GetBValue(SrcImage[ty+1][tx]); blue[2] = GetBValue(SrcImage[ty][tx+1]); blue[3] = GetBValue(SrcImage[ty+1][tx+1]); r = 0; g = 0; b = 0; for(int m = 0;m<4;m++) { r += pm[m] * red[m]; g += pm[m] * green[m]; b += pm[m] * blue[m]; } // DesImage[i][j] = pm[0] * SrcImage[ty][tx] + pm[1] * SrcImage[ty][tx+1] + pm[2] * SrcImage[ty+1][tx] + pm[3] * SrcImage[ty+1][tx+1]; // DesImage[i][j] = SrcImage[ty][tx]; DesImage[i][j] = RGB(r,g,b); // DesImage[i][j] = (SrcImage[ty][tx]+SrcImage[ty][tx+1]+ SrcImage[ty+1][tx]+SrcImage[ty+1][tx+1])/4; } } LImage = DesImage; }