public class ImageTool
{
/// <summary>
/// 转化图片颜色,输入目标图片宽高数值,那么目标图片会被比例缩放
/// </summary>
/// <param name="filePath">原图片路径</param>
/// <param name="destHeight">目标图片高度</param>
/// <param name="destWidth">目标图片宽度</param>
/// <param name="uc">是否执行转化动作</param>
/// <returns></returns>
public static string ZoomImage(string filePath, int destHeight, int destWidth, bool uc)
{
Bitmap bitmap = new Bitmap(Image.FromFile(filePath));
if (uc)
{
bitmap = UpdateColor(bitmap);
}
Bitmap finalmap = ZoomImage(bitmap, destHeight, destWidth);
string zoomFilePath = GetZoomFilePath(filePath);
finalmap.Save(zoomFilePath);
return zoomFilePath;
}
private static Bitmap UpdateColor(Bitmap bitmap)
{
int width = bitmap.Width;
int height = bitmap.Height;
Bitmap newmap = new Bitmap(width, height);
Color pixel;
for(int i=0; i< width; i++)
{
for (int j = 0; j < height; j++)
{
pixel = bitmap.GetPixel(i, j); // 获取原图的像素点颜色值
int r, g, b, a;
r = pixel.R;
g = pixel.G;
b = pixel.B;
a = pixel.A;
// 判断是否为白色背景
if (r == 255 && g == 255 && b == 255)
{
newmap.SetPixel(i, j, Color.FromArgb(255, 255, 255));
}
else
{
newmap.SetPixel(i, j, Color.Red);
}
}
}
return newmap;
}
/// <summary>
/// 获取目标图片文件名称
/// </summary>
/// <param name="filePath">原图片路径</param>
/// <returns></returns>
private static string GetZoomFilePath(string filePath)
{
string ext = filePath.Substring(filePath.LastIndexOf('.'));
string zoomFilePath = filePath.Substring(0, filePath.LastIndexOf('.')) + "_zoom" + ext;
return zoomFilePath;
}
/// <summary>
/// 等比例缩放图片
/// </summary>
/// <param name="bitmap">原图片位图对象</param>
/// <param name="destHeight">目标图片高度</param>
/// <param name="destWidth">目标图片宽度</param>
/// <returns></returns>
private static Bitmap ZoomImage(Bitmap bitmap, int destHeight, int destWidth)
{
try
{
System.Drawing.Image sourImage = bitmap;
int width = 0, height = 0;
//按比例缩放
int sourWidth = sourImage.Width;
int sourHeight = sourImage.Height;
// 判断原图与目标图片的宽高,如果目标图片的宽或高比原图要小的话,那么执行缩放,计算缩放后的宽高数值
if (sourHeight > destHeight || sourWidth > destWidth)
{
// 原图宽/目标图片宽 与 原图高/目标图片高,对两者的缩放比例进行比较
// 如果宽的缩放比例大于高的缩放比例,则保留目标图片设定的宽度,动态计算缩放后新的高度
// 此处计算的width 和 height 均为目标图片中新的图像绘制区域的宽和高,而不是整张图片的宽和高
// 目标图片的宽和高始终保持在预定的 destWidth 和 destHeight
if ((sourWidth * destHeight) > (sourHeight * destWidth))
{
width = destWidth;
height = (destWidth * sourHeight) / sourWidth;
}
else
{
height = destHeight;
width = (sourWidth * destHeight) / sourHeight;
}
}
else
{
width = sourWidth;
height = sourHeight;
}
// 目标图片位图对象
Bitmap destBitmap = new Bitmap(destWidth, destHeight);
// 产生画笔
Graphics g = Graphics.FromImage(destBitmap);
// 背景色透明
g.Clear(Color.Transparent);
//设置画布的描绘质量
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// 此时的width 和 height 均为缩放后图片中图像区域的宽高,与原先设定的宽高数值相减之后再除以2,可动态计算出原图绘制到目标图片后的左边距和上边距,目的是使图片尽可能保持居中效果
g.DrawImage(sourImage, new System.Drawing.Rectangle((destWidth - width) / 2, (destHeight - height) / 2, width, height), 0, 0, sourImage.Width, sourImage.Height, GraphicsUnit.Pixel);
g.Dispose();
//设置压缩质量
System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
long[] quality = new long[1];
quality[0] = 100;
System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
encoderParams.Param[0] = encoderParam;
sourImage.Dispose();
return destBitmap;
}
catch
{
return bitmap;
}
}
}
下面将图解说明,计算缩放比例的逻辑,为什么要这么写
最终的结果,会是下图的样子