目录
应用场景
我们假设会有如下场景:
场景1:培训系统中,在上传课件培训视频素材的功能,我们会上传课程封面图片,将来会在课程详情内容中在指定的位置输出。
场景2:人才网站中,企业端管理后台,会上传企业的 LOGO 内容图片,用于企业介绍页面或岗位招聘详情页面等。
场景3:商城系统中,商品发布后台,会上传商品的主图宣传图片及其它关键介绍性图片,用于商品详情页面中进行展示、宣传。
以上等场景都会使用一个通用的功能,查询。查询的一个特征点,是会显示如上场景中涉及的课程封面图、企业LOGO图和商品主宣传图。通常为了提高查询性能显示效率,会在查询列表中显示原有图片的缩略图,因为为了达到显示效果,详情信息里的图片毕竟质量比较高、尺寸比较大。
因此,生成缩略图主要要达到以下目的:
1、缩略图通过压缩技术在尽量保证显示质量的情况下,能够在 Web 浏览器中更加迅速地载入数据。
2、较小的数据量可以节省流量成本。
3、制作存储新的缩略图(仅用于查询时显示)可以更加直观的吸引用户,提高系统体验感。
开发运行环境
操作系统: Windows Server 2019 DataCenter
.net版本: .netFramework4.0 或以上
开发工具:VS2019 C#
方法设计
public Byte[] MakeThumbnail 方法(制作缩略图)调用参数见如下表格:
| 序号 |        参数         |                      类型                      |                                          说明                                           |
| 1  | originalImagePath |                    string                    |                                   物理路径图片文件地址,非唯一选项                                    |
| 2  |      bvalue       |                   Byte[]                   |                                  Byte[] 类型数据,非唯一选项                                  |
| 3  |   thumbnailPath   |                    string                    |            非必选项,方法返回压缩后的 Byte[]数组数据,如果同时指定输出文件路径 thumbnailPath,则同时生成这个文件            |
| 4  |      width=0      |                     int                      |                              指定输出缩略图的宽width,默认为0,表示为原图的宽                              |
| 5  |     height=0      |                     int                      |                             指定输出缩略图的高height,默认为0,表示为原图的高                              |
| 6  |       mode        |                    string                    | mode为压缩方法:"HW":指定高宽缩放(可能变形),"W":指定宽,高按比例 ,"H":指定高,宽按比例 , "Cut":指定高宽裁减(不变形),参数默认="Cut" |
| 7 | interpolationMode | System.Drawing. Drawing2D. InterpolationMode | 指定在缩放或旋转图像时使用的算法,默认值 = System.Drawing.Drawing2D.InterpolationMode.High | 
|---|
物理路径文件 originalImagePath 或 Byte[]型数据 bvalue,两者同时传递以物理路径文件优先。
实现代码
方法代码
            
            
              cs
              
              
            
          
          //制作缩略图(压缩图),可接收两种参数,物理路径文件 originalImagePath 或 Byte[]型数据 bvalue,两者同时传递以物理路径文件优先。
//方法返回压缩后的 Byte[]数组数据,如果同时指定输出文件路径thumbnailPath,则同时生成这个文件。
//指定输出缩略图的宽width和高height,如果为0,则默认为原图的宽或高
//mode为压缩方法:"HW":指定高宽缩放(可能变形),"W":指定宽,高按比例 ,"H":指定高,宽按比例 , "Cut":指定高宽裁减(不变形)
public  Byte[] MakeThumbnail(string originalImagePath, Byte[] bvalue, string thumbnailPath, int width=0, int height=0, string mode="Cut", System.Drawing.Drawing2D.InterpolationMode interpolationMode= System.Drawing.Drawing2D.InterpolationMode.High)
{
                System.Drawing.Image originalImage;
                if (originalImagePath != "")
                {
                    originalImage = System.Drawing.Image.FromFile(originalImagePath);
                }
                else
                {
                    originalImage = System.Drawing.Image.FromStream(new System.IO.MemoryStream(bvalue));
                }
                int towidth = width;
                int toheight = height;
                int x = 0;
                int y = 0;
                int ow = originalImage.Width;
                int oh = originalImage.Height;
                if (towidth == 0)
                {
                    towidth = ow;
                }
                if (toheight == 0)
                {
                    toheight = oh;
                }
                switch (mode)
                {
                    case "HW"://指定高宽缩放(可能变形)                 
                        break;
                    case "W"://指定宽,高按比例                     
                        toheight = originalImage.Height * towidth / originalImage.Width;
                        break;
                    case "H"://指定高,宽按比例 
                        towidth = originalImage.Width * toheight / originalImage.Height;
                        break;
                    case "Cut"://指定高宽裁减(不变形)                 
                        if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
                        {
                            oh = originalImage.Height;
                            ow = originalImage.Height * towidth / toheight;
                            y = 0;
                            x = (originalImage.Width - ow) / 2;
                        }
                        else
                        {
                            ow = originalImage.Width;
                            oh = originalImage.Width * toheight / towidth;
                            x = 0;
                            y = (originalImage.Height - oh) / 2;
                        }
                        break;
                    default:
                        break;
                }
                //新建一个bmp图片 
                System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
                //新建一个画板 
                System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
                //设置高质量插值法 
                g.InterpolationMode = interpolationMode ;
                //设置高质量,低速度呈现平滑程度 
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                //清空画布并以透明背景色填充 
                g.Clear(System.Drawing.Color.Transparent);
                //在指定位置并且按指定大小绘制原图片的指定部分 
                g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight),
                    new System.Drawing.Rectangle(x, y, ow, oh),
                    System.Drawing.GraphicsUnit.Pixel);
                try
                {
                    //以jpg格式保存缩略图 
                    System.IO.MemoryStream mstream = new System.IO.MemoryStream();
                    System.Drawing.Imaging.ImageFormat format = originalImage.RawFormat;
                    System.Drawing.Imaging.ImageFormat toFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
                    if (format.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
                    {
                        toFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
                    }
                    else if (format.Equals(System.Drawing.Imaging.ImageFormat.Png))
                    {
                        toFormat = System.Drawing.Imaging.ImageFormat.Png;
                    }
                    else if (format.Equals(System.Drawing.Imaging.ImageFormat.Bmp))
                    {
                        toFormat = System.Drawing.Imaging.ImageFormat.Bmp;
                    }
                    else if (format.Equals(System.Drawing.Imaging.ImageFormat.Gif))
                    {
                        toFormat = System.Drawing.Imaging.ImageFormat.Gif;
                    }
                    else if (format.Equals(System.Drawing.Imaging.ImageFormat.Icon))
                    {
                        toFormat = System.Drawing.Imaging.ImageFormat.Icon;
                    }
                    else if (format.Equals(System.Drawing.Imaging.ImageFormat.Emf))
                    {
                        toFormat = System.Drawing.Imaging.ImageFormat.Emf;
                    }
                    else if (format.Equals(System.Drawing.Imaging.ImageFormat.Exif))
                    {
                        toFormat = System.Drawing.Imaging.ImageFormat.Exif;
                    }
                    else if (format.Equals(System.Drawing.Imaging.ImageFormat.Tiff))
                    {
                        toFormat = System.Drawing.Imaging.ImageFormat.Tiff;
                    }
                    else if (format.Equals(System.Drawing.Imaging.ImageFormat.Wmf))
                    {
                        toFormat = System.Drawing.Imaging.ImageFormat.Wmf;
                    }
                    bitmap.Save(mstream, toFormat);
                    
                    byte[] byData = new Byte[mstream.Length];
                    mstream.Position = 0;
                    mstream.Read(byData, 0, byData.Length);
                    mstream.Close();
                    if (thumbnailPath != "")
                    {
                        bitmap.Save(thumbnailPath, toFormat);
                    }
                    return byData;
                }
                catch (System.Exception e)
                {
                    throw e;
                }
                finally
                {
                    originalImage.Dispose();
                    bitmap.Dispose();
                    g.Dispose();
                }
}
        调用示例
本调用示例实现判断上传的图像大小,如果图像大于2Mb则自动进行压缩处理。
            
            
              cs
              
              
            
          
          string upfilename = Request.PhysicalApplicationPath + "\\upload.jpg"; //上传的图片路径
string mtfilename = Request.PhysicalApplicationPath + "\\mt.jpg";  //缩略图的图片路径
if (System.IO.File.Exists(upfilename))
{
    FileInfo fileInfo = new FileInfo(upfilename);
    float _fsize = fileInfo.Length / (1024*1024);
    if (_fsize >= 2)
    {
        MakeThumbnail(upfilename, null, mtfilename);
    }
    else
    {
        mtfilename = upfilename;
    }
    Response.Write("Result Filename is :"+mtfilename);
}
        小结
输出缩略图可以采取动态输出和静态存储方式,动态输出耗性能,静态存储耗空间,我们可以以空间换时间来获取更高的性能。我们需要根据项目的实际情况来决定采用哪种方式比较平衡。
感谢您的阅读,希望本文能够对您有所帮助。