是这一个几年前写的相册代码里翻出来的,我惊呆了还曾经编过这样的东西,可能比我现在的代码写得要好。
虽然有完整的注释,我一时间都没看明白,更别提当初是怎么编的它。
自己的代码尚且如此。还是说,有时候代码是不是自己都无所谓……
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Drawing;
/// <summary>
/// 生成缩略图 v1.0.01 开发版
/// </summary>
public class ViewPic
{
public ViewPic()
{
//TODO: 在此处添加构造函数逻辑
}
private struct ImageSize
{
public int Width;
public int Height;
}
private ImageSize pic; // 由GetPicSize()获取原图尺寸
private ImageSize view; // 由ImageResize()计算适应缩图尺寸后的大小
/// <summary>
/// 读取一个图像文件的宽和高,设置到pic属性
/// </summary>
/// <param name="path">文件路径</param>
private void GetPicSize(string path)
{
try
{
Image T1 = Image.FromFile(path);
pic.Width = T1.Width;
pic.Height = T1.Height;
T1.Dispose();
}
catch(Exception er)
{
Console.Write(er.ToString());
}
finally
{ }
return;
}
/// <summary>
/// 自适应式的计算缩图宽和高,保持图像比例
/// 会引用到本类中pic的值,结果保存到view中
/// 所以这是一个私有成员
/// </summary>
/// <param name="W">期望缩图的宽</param>
/// <param name="H">期望缩图的高</param>
private void ImageResize(int W, int H)
{
// 特殊情况:原图比缩图还小
if (pic.Width < W && pic.Height < H)
{
// 不变
view.Width = pic.Width;
view.Height = pic.Height;
return;
}
// 正常情况:进行图像大小的计算
if (pic.Width == pic.Height)
{
// 图像宽高相同
view.Width = view.Height = (H < W) ? H : W;
}
else if ((float)pic.Width / (float)pic.Height > (float)W / (float)H)
{
// 图像宽高比大于缩图宽高比,适应宽度
view.Width = W;
view.Height = (int)(pic.Height * (W / (float)pic.Width));
}
else if ((float)pic.Width / (float)pic.Height < (float)W / (float)H)
{
// 图像宽高比小于缩图宽高比,适应高度
view.Height = H;
view.Width = (int)(pic.Width * (H / (float)pic.Height));
}
else if ((float)pic.Width / (float)pic.Height == (float)W / (float)H)
{
// 宽高比相同
view.Width = W;
view.Height = H;
}
return;
}
/// <summary>
/// 生成缩图
/// </summary>
/// <param name="SourcePath">源始图片的完整路径</param>
/// <param name="ViewPath">生成后的缩图保存位置,完整路径</param>
/// <param name="Width">期望生成缩图的宽度(范围)</param>
/// <param name="Height">期望生成缩图的宽度(范围)</param>
public void MakeViewPicture(string SourcePath, string ViewPath, int Width, int Height)
{
// 首先是对参数的有效性做验证。
if (!File.Exists(SourcePath)) return; // 如果源始文件不存在,就直接返回。
if (File.Exists(ViewPath)) // 输出位置已经存在文件
{
// 将对应的操作放在这里
// 放弃操作,返回
return;
}
if (Width <= 0 || Height <= 0) return; // 参数不能为0或负数,返回。
// 打开原始图像
Image originalImage = Image.FromFile(SourcePath);
// 获取原图像的大小,结果在属性[pic]中
GetPicSize(SourcePath);
// 按照期望的缩略图范围值,重新计算出最适合宽和高,结果在属性[view]中
ImageResize(Width, Height);
// 新建一个位图
Image viewbmp = new Bitmap(view.Width, view.Height);
// 新建一个绘图
Graphics g = Graphics.FromImage(viewbmp);
// 设置图像质量
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//清空画布并以透明背景色填充
g.Clear(Color.Transparent);
// 复制 生成缩图
g.DrawImage(originalImage,
new Rectangle(0, 0, view.Width, view.Height),
new Rectangle(0, 0, pic.Width, pic.Height),
GraphicsUnit.Pixel);
try
{
// 以JPE格式保存缩图
viewbmp.Save(ViewPath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception er)
{
Console.Write(er.ToString());
}
finally
{
originalImage.Dispose();
viewbmp.Dispose();
g.Dispose();
}
}
/// <summary>
/// 返回文件的一系列信息
/// </summary>
/// <param name="path">文件的路径</param>
/// <returns>
/// 一个包含文件信息内容的字串,例如:
/// "800×600 [847KB] ()"
/// </returns>
public string GetInfo(string path)
{
if (!File.Exists(path)) return String.Empty;
int X, Y;
int FileSize;
// 图像的宽和高
Image T1 = Image.FromFile(path);
X = T1.Width;
Y = T1.Height;
T1.Dispose();
// 图像文件的大小
FileInfo fl = new FileInfo(path);
FileSize = (int)fl.Length / 1024; //返回文件长度,单位KB
// 文件建立的时间
DateTime DT = File.GetCreationTime(path);
return X.ToString() + "×" + Y.ToString() +
String.Format(" [{0}KB]", FileSize.ToString("0,0")) +
String.Format(" ({0})",DT.ToString());
}
}