代码出自该贴 2楼。
http://topic.csdn.net/u/20090420/00/4042e404-e802-45f7-8b25-c7fbc5a81c76.html
代码没有注释看了好久都没看不懂。
希望有图像处理方面经验的朋友帮忙解释一下。添加以下注释。
代码实现的是图片的缩放。
/// <summary>
/// 缩放
/// </summary>
/// <param name="newWidth">宽</param>
/// <param name="newHeight">高</param>
public void Resize(int newWidth, int newHeight)
{
if (newWidth != 0 && newHeight != 0)
{
Bitmap temp = (Bitmap)_currentBitmap;
Bitmap bmap = new Bitmap(newWidth, newHeight, temp.PixelFormat); double nWidthFactor = (double)temp.Width / (double)newWidth;
double nHeightFactor = (double)temp.Height / (double)newHeight; double fx, fy, nx, ny;
int cx, cy, fr_x, fr_y;
Color color1 = new Color();
Color color2 = new Color();
Color color3 = new Color();
Color color4 = new Color();
byte nRed, nGreen, nBlue; byte bp1, bp2; for (int x = 0; x < bmap.Width; ++x)
{
for (int y = 0; y < bmap.Height; ++y)
{ fr_x = (int)Math.Floor(x * nWidthFactor);
fr_y = (int)Math.Floor(y * nHeightFactor);
cx = fr_x + 1;
if (cx >= temp.Width) cx = fr_x;
cy = fr_y + 1;
if (cy >= temp.Height) cy = fr_y;
fx = x * nWidthFactor - fr_x;
fy = y * nHeightFactor - fr_y;
nx = 1.0 - fx;
ny = 1.0 - fy; color1 = temp.GetPixel(fr_x, fr_y);
color2 = temp.GetPixel(cx, fr_y);
color3 = temp.GetPixel(fr_x, cy);
color4 = temp.GetPixel(cx, cy); // Blue
bp1 = (byte)(nx * color1.B + fx * color2.B); bp2 = (byte)(nx * color3.B + fx * color4.B); nBlue = (byte)(ny * (double)(bp1) + fy * (double)(bp2)); // Green
bp1 = (byte)(nx * color1.G + fx * color2.G); bp2 = (byte)(nx * color3.G + fx * color4.G); nGreen = (byte)(ny * (double)(bp1) + fy * (double)(bp2)); // Red
bp1 = (byte)(nx * color1.R + fx * color2.R); bp2 = (byte)(nx * color3.R + fx * color4.R); nRed = (byte)(ny * (double)(bp1) + fy * (double)(bp2)); bmap.SetPixel(x, y, System.Drawing.Color.FromArgb(255, nRed, nGreen, nBlue));
}
}
_currentBitmap = (Bitmap)bmap.Clone();
}
}
http://topic.csdn.net/u/20090420/00/4042e404-e802-45f7-8b25-c7fbc5a81c76.html
代码没有注释看了好久都没看不懂。
希望有图像处理方面经验的朋友帮忙解释一下。添加以下注释。
代码实现的是图片的缩放。
/// <summary>
/// 缩放
/// </summary>
/// <param name="newWidth">宽</param>
/// <param name="newHeight">高</param>
public void Resize(int newWidth, int newHeight)
{
if (newWidth != 0 && newHeight != 0)
{
Bitmap temp = (Bitmap)_currentBitmap;
Bitmap bmap = new Bitmap(newWidth, newHeight, temp.PixelFormat); double nWidthFactor = (double)temp.Width / (double)newWidth;
double nHeightFactor = (double)temp.Height / (double)newHeight; double fx, fy, nx, ny;
int cx, cy, fr_x, fr_y;
Color color1 = new Color();
Color color2 = new Color();
Color color3 = new Color();
Color color4 = new Color();
byte nRed, nGreen, nBlue; byte bp1, bp2; for (int x = 0; x < bmap.Width; ++x)
{
for (int y = 0; y < bmap.Height; ++y)
{ fr_x = (int)Math.Floor(x * nWidthFactor);
fr_y = (int)Math.Floor(y * nHeightFactor);
cx = fr_x + 1;
if (cx >= temp.Width) cx = fr_x;
cy = fr_y + 1;
if (cy >= temp.Height) cy = fr_y;
fx = x * nWidthFactor - fr_x;
fy = y * nHeightFactor - fr_y;
nx = 1.0 - fx;
ny = 1.0 - fy; color1 = temp.GetPixel(fr_x, fr_y);
color2 = temp.GetPixel(cx, fr_y);
color3 = temp.GetPixel(fr_x, cy);
color4 = temp.GetPixel(cx, cy); // Blue
bp1 = (byte)(nx * color1.B + fx * color2.B); bp2 = (byte)(nx * color3.B + fx * color4.B); nBlue = (byte)(ny * (double)(bp1) + fy * (double)(bp2)); // Green
bp1 = (byte)(nx * color1.G + fx * color2.G); bp2 = (byte)(nx * color3.G + fx * color4.G); nGreen = (byte)(ny * (double)(bp1) + fy * (double)(bp2)); // Red
bp1 = (byte)(nx * color1.R + fx * color2.R); bp2 = (byte)(nx * color3.R + fx * color4.R); nRed = (byte)(ny * (double)(bp1) + fy * (double)(bp2)); bmap.SetPixel(x, y, System.Drawing.Color.FromArgb(255, nRed, nGreen, nBlue));
}
}
_currentBitmap = (Bitmap)bmap.Clone();
}
}
// 调整大小
public void Resize(int newWidth, int newHeight)
{
if (newWidth != 0 && newHeight != 0) // 新宽高必须有值
{
Bitmap temp = (Bitmap)_currentBitmap; // 临时 Bitmap 型图像对像,_currentBitmap 是一个本地变量,可能是 Image 型引用
Bitmap bmap = new Bitmap(newWidth, newHeight, temp.PixelFormat); // 建立新 Bitmap,使其宽高与参数同,并使用 temp 的像素设置 double nWidthFactor = (double)temp.Width / (double)newWidth; // 宽之倍因值,用于缩放
double nHeightFactor = (double)temp.Height / (double)newHeight; // 高之倍因值,用于缩放 double fx, fy, nx, ny;
int cx, cy, fr_x, fr_y;
Color color1 = new Color(); // 生成四个 Color 对像,用于着色
Color color2 = new Color();
Color color3 = new Color();
Color color4 = new Color();
byte nRed, nGreen, nBlue; byte bp1, bp2;
// 两层 for 遍历 bmap 对像的所有像素点
for (int x = 0; x < bmap.Width; ++x)
{
for (int y = 0; y < bmap.Height; ++y)
{
fr_x = (int)Math.Floor(x * nWidthFactor); // 横轴缩放值,用于像素点的映射
fr_y = (int)Math.Floor(y * nHeightFactor); // 纵轴缩放值,用于像素点的映射
cx = fr_x + 1; // fr_x 像素点横向量的下一点
if (cx >= temp.Width) cx = fr_x;
cy = fr_y + 1; // fr_y 像素点纵向量的下一点
if (cy >= temp.Height) cy = fr_y;
fx = x * nWidthFactor - fr_x; // 宽取补
fy = y * nHeightFactor - fr_y; // 高取补
nx = 1.0 - fx; // 比例值
ny = 1.0 - fy; color1 = temp.GetPixel(fr_x, fr_y); // 取得 temp 在 (fr_x, fr_y) 处的像素点
color2 = temp.GetPixel(cx, fr_y);
color3 = temp.GetPixel(fr_x, cy);
color4 = temp.GetPixel(cx, cy); // Blue
bp1 = (byte)(nx * color1.B + fx * color2.B); bp2 = (byte)(nx * color3.B + fx * color4.B); nBlue = (byte)(ny * (double)(bp1) + fy * (double)(bp2)); // Green
bp1 = (byte)(nx * color1.G + fx * color2.G); bp2 = (byte)(nx * color3.G + fx * color4.G); nGreen = (byte)(ny * (double)(bp1) + fy * (double)(bp2)); // Red
bp1 = (byte)(nx * color1.R + fx * color2.R); bp2 = (byte)(nx * color3.R + fx * color4.R); nRed = (byte)(ny * (double)(bp1) + fy * (double)(bp2));
// 三元色置完后,向 bmap 的 (x,y) 点置像素点
bmap.SetPixel(x, y, System.Drawing.Color.FromArgb(255, nRed, nGreen, nBlue));
}
}
_currentBitmap = (Bitmap)bmap.Clone(); // 更新本地变量为 bmap 的复本保存下来。
}
}
思想是:
新图的每个点关联原图的四个点进行映射,(fr_x, fr_y)、(cx, fr_y)、(fr_x, cy)、(cx, cy),这四个点每个都有权重值nx、fx、ny、fy,每个点像素bgr
可以通过在每个四个点的bgr的值乘上权值来计算。
1、Nearest Point,用最近的点的颜色,比如离旧图的第5点更近,则用第5点的颜色(最快,但图像质量不好)。
2、Bilinear,双线形插值,近的点权重大,远的点权重小(慢一些,图像质量比较好)。
3、Bicubic,双三次插值,颜色通过最近的16个采样点的加权平均得到(图像质量一般很好,但还会慢一些)。
楼主贴的算法属于第二种方法,颜色由最近的四个点线形插值得到。