将缩放后的图像坐标通过反向变换得到的一个浮点坐标,将浮点坐标在原图像应位置周围的4(2×2)个像素根据某种权值进行加权运算得到的像素值就是缩放后目的像素的像素值。双线性插值缩放后图像质量高,极大地消除了锯齿现象,不会出现像素值不连续的的情况,但由于其具有低通滤波器的性质,使高频分量受损,所以可能会使图像轮廓在一定程度上变得模糊。
设原图像为f(x,y),缩放后的图像为g(u,v),水平缩放系数为ZoomX,竖直缩放系数为ZoomY,则使用下面的方法计算使用双线性插值法缩放后的像素值。
令
x' = [u/ZoomX], y' = [v/ZoomY];
m = u/ZoomX - x', n = v/ZoomY - y';
其中[]符号表示对括号包络的部分取整数部分。
则有
g(u,v)= (1-m)×(1-n)× f(x',y')+ (1-m)×n× f(x',y'+1)
+m×(1-n)× f(x'+1,y') + m×n×f(x'+1,y'+1);
void ZoomBitMap(unsigned char *pSrcImg, unsigned char *pDstImg, int nWidth, int nHeight, float fRate)
{
int i = 0;
int j = 0;
float fX, fY;
int iStepSrcImg = nWidth;
int iStepDstImg = nWidth * fRate;
int iX, iY;
unsigned char bUpLeft, bUpRight, bDownLeft, bDownRight;
unsigned char gUpLeft, gUpRight, gDownLeft, gDownRight;
unsigned char rUpLeft, rUpRight, rDownLeft, rDownRight;
unsigned char b, g, r;
for(i = 0; i < nHeight * fRate; i++)
{
for(j = 0; j < nWidth * fRate; j++)
{
fX = ((float)j) /fRate;
fY = ((float)i) /fRate;
iX = (int)fX;
iY = (int)fY;
bUpLeft = pSrcImg[iY * iStepSrcImg * 3 + iX * 3 + 0];
bUpRight = pSrcImg[iY * iStepSrcImg * 3 + (iX + 1) * 3 + 0];
bDownLeft = pSrcImg[(iY + 1) * iStepSrcImg * 3 + iX * 3 + 0];
bDownRight = pSrcImg[(iY + 1) * iStepSrcImg * 3 + (iX + 1) * 3 + 0];
gUpLeft = pSrcImg[iY * iStepSrcImg * 3 + iX * 3 + 1];
gUpRight = pSrcImg[iY * iStepSrcImg * 3 + (iX + 1) * 3 + 1];
gDownLeft = pSrcImg[(iY + 1) * iStepSrcImg * 3 + iX * 3 + 1];
gDownRight = pSrcImg[(iY + 1) * iStepSrcImg * 3 + (iX + 1) * 3 + 1];
rUpLeft = pSrcImg[iY * iStepSrcImg * 3 + iX * 3 + 2];
rUpRight = pSrcImg[iY * iStepSrcImg * 3 + (iX + 1) * 3 + 2];
rDownLeft = pSrcImg[(iY + 1) * iStepSrcImg * 3 + iX * 3 + 2];
rDownRight = pSrcImg[(iY + 1) * iStepSrcImg * 3 + (iX + 1) * 3 + 2];
b = bUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + bUpRight * (fX - iX) * (iY + 1 - fY)
+ bDownLeft * (iX + 1 - fX) * (fY - iY) + bDownRight * (fX - iX) * (fY - iY);
g = gUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + gUpRight * (fX - iX) * (iY + 1 - fY)
+ gDownLeft * (iX + 1 - fX) * (fY - iY) + gDownRight * (fX - iX) * (fY - iY);
r = rUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + rUpRight * (fX - iX) * (iY + 1 - fY)
+ rDownLeft * (iX + 1 - fX) * (fY - iY) + rDownRight * (fX - iX) * (fY - iY);
if(iY >= 0 && iY <= nHeight * 2 && iX >= 0 && iX <= nWidth * 2)
{
pDstImg[i * iStepDstImg * 3 + j * 3 + 0] = b; //B
pDstImg[i * iStepDstImg * 3 + j * 3 + 1] = g; //G
pDstImg[i * iStepDstImg * 3 + j * 3 + 2] = r; //R
}
}
}
}