根据维基百科的定义:
双线性插值,又称为双线性内插。在数学上,双线性插值是对线性插值在二维直角网格上的扩展,用于对双变量函数(例如 x 和 y)进行插值。其核心思想是在两个方向分别进行一次线性插值。
定义一个函数方法ReClass
//使用双线性插值法进行重采样
private Bitmap ReClass(Bitmap bitmap)
{
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
//得到横坐标和纵坐标的缩放量
double x =2;
double y =2.5;
//图像的几何中心
int halfHeight = (int)(bitmap.Height / 2);
int halfWidth = (int)(bitmap.Width / 2);
int xz = 0;
int yz = 0;
int tempWidth = 0;
int tempHeight = 0;
int bytes = bitmap.Width * bitmap.Height;
byte[] grayValues = new byte[bytes];
byte[] tempArray = new byte[bytes];
double tempX, tempY, p, q;
for (int i = 0; i < bitmap.Height; i++)
{
for (int j = 0; j < bitmap.Width; j++)
{
//以图像的几何中心为坐标进行坐标变换
//按逆向映射法得到输入图像的坐标
tempHeight = i - halfHeight;
tempWidth = j - halfWidth;
tempX = tempWidth / x;
tempY = tempHeight / y;
//在不同象限内进行取整处理
if (tempWidth > 0)
{
xz = (int)tempX;
}
else
{
xz = (int)(tempX - 1);
}
if (tempHeight > 0)
{
yz = (int)tempY;
}
else
{
yz = (int)(tempY - 1);
}
//得到灰度插值法的公式中的变量p和q
p = tempX - xz;
q = tempY - yz;
//坐标逆变换
tempWidth = xz + halfWidth;
tempHeight = yz + halfHeight;
if (tempWidth < 0 || (tempWidth + 1) >= bitmap.Width || tempHeight < 0 || (tempHeight + 1) >= bitmap.Height)
{
//缩放后留下空白的空间用白色像素代替
tempArray[i * bitmap.Width + j] = 255;
}
else
{
tempArray[i * bitmap.Width + j] = (byte)((1.0 - q) * (1.0 - p) * grayValues[tempHeight * bitmap.Width + tempWidth] + p*grayValues[tempWidth*bitmap.Width+tempWidth+1]+q*(1.0-p)*grayValues[(tempHeight+1)*bitmap.Width+tempWidth]+p*grayValues[(tempHeight+1)*bitmap.Width+1+tempWidth]);
}
}
}
grayValues = (byte[])tempArray.Clone();
System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
bitmap.UnlockBits(bmpData);
return bitmap;
}
然后在主函数中对这个方法进行应用
picturebox1.Image = ReClass(curBitmap);//curBitmap代表但前的二进制图像