• C# 生成指定图片的缩略图


    目录

    应用场景

    开发运行环境

    方法设计

    实现代码

    方法代码

    调用示例

    小结


    应用场景

    我们假设会有如下场景:

    场景1:培训系统中,在上传课件培训视频素材的功能,我们会上传课程封面图片,将来会在课程详情内容中在指定的位置输出。

    场景2:人才网站中,企业端管理后台,会上传企业的 LOGO 内容图片,用于企业介绍页面或岗位招聘详情页面等。

    场景3:商城系统中,商品发布后台,会上传商品的主图宣传图片及其它关键介绍性图片,用于商品详情页面中进行展示、宣传。

    以上等场景都会使用一个通用的功能,查询。查询的一个特征点,是会显示如上场景中涉及的课程封面图、企业LOGO图和商品主宣传图。通常为了提高查询性能显示效率,会在查询列表中显示原有图片的缩略图,因为为了达到显示效果,详情信息里的图片毕竟质量比较高、尺寸比较大。

    因此,生成缩略图主要要达到以下目的:

    1、缩略图通过压缩技术在尽量保证显示质量的情况下,能够在 Web 浏览器中更加迅速地载入数据。

    2、较小的数据量可以节省流量成本。

    3、制作存储新的缩略图(仅用于查询时显示)可以更加直观的吸引用户,提高系统体验感。

    开发运行环境

    操作系统: Windows Server 2019 DataCenter

    .net版本: .netFramework4.0 或以上

    开发工具:VS2019  C#

    方法设计

    public  Byte[] MakeThumbnail 方法(制作缩略图)调用参数见如下表格:

    序号参数类型说明
    1originalImagePathstring物理路径图片文件地址,非唯一选项 
    2bvalueByte[]Byte[] 类型数据,非唯一选项
    3thumbnailPathstring非必选项,方法返回压缩后的 Byte[]数组数据,如果同时指定输出文件路径 thumbnailPath,则同时生成这个文件
    4width=0int指定输出缩略图的宽width,默认为0,表示为原图的宽
    5height=0int指定输出缩略图的高height,默认为0,表示为原图的高
    6modestringmode为压缩方法:"HW":指定高宽缩放(可能变形),"W":指定宽,高按比例 ,"H":指定高,宽按比例 , "Cut":指定高宽裁减(不变形),参数默认="Cut"
    7interpolationMode

    System.Drawing.

    Drawing2D.

    InterpolationMode

    指定在缩放或旋转图像时使用的算法,默认值

    = System.Drawing.Drawing2D.InterpolationMode.High

    物理路径文件 originalImagePath 或 Byte[]型数据 bvalue,两者同时传递以物理路径文件优先。

    实现代码

    方法代码

    1. //制作缩略图(压缩图),可接收两种参数,物理路径文件 originalImagePath 或 Byte[]型数据 bvalue,两者同时传递以物理路径文件优先。
    2. //方法返回压缩后的 Byte[]数组数据,如果同时指定输出文件路径thumbnailPath,则同时生成这个文件。
    3. //指定输出缩略图的宽width和高height,如果为0,则默认为原图的宽或高
    4. //mode为压缩方法:"HW":指定高宽缩放(可能变形),"W":指定宽,高按比例 ,"H":指定高,宽按比例 , "Cut":指定高宽裁减(不变形)
    5. 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)
    6. {
    7. System.Drawing.Image originalImage;
    8. if (originalImagePath != "")
    9. {
    10. originalImage = System.Drawing.Image.FromFile(originalImagePath);
    11. }
    12. else
    13. {
    14. originalImage = System.Drawing.Image.FromStream(new System.IO.MemoryStream(bvalue));
    15. }
    16. int towidth = width;
    17. int toheight = height;
    18. int x = 0;
    19. int y = 0;
    20. int ow = originalImage.Width;
    21. int oh = originalImage.Height;
    22. if (towidth == 0)
    23. {
    24. towidth = ow;
    25. }
    26. if (toheight == 0)
    27. {
    28. toheight = oh;
    29. }
    30. switch (mode)
    31. {
    32. case "HW"://指定高宽缩放(可能变形)
    33. break;
    34. case "W"://指定宽,高按比例
    35. toheight = originalImage.Height * towidth / originalImage.Width;
    36. break;
    37. case "H"://指定高,宽按比例
    38. towidth = originalImage.Width * toheight / originalImage.Height;
    39. break;
    40. case "Cut"://指定高宽裁减(不变形)
    41. if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
    42. {
    43. oh = originalImage.Height;
    44. ow = originalImage.Height * towidth / toheight;
    45. y = 0;
    46. x = (originalImage.Width - ow) / 2;
    47. }
    48. else
    49. {
    50. ow = originalImage.Width;
    51. oh = originalImage.Width * toheight / towidth;
    52. x = 0;
    53. y = (originalImage.Height - oh) / 2;
    54. }
    55. break;
    56. default:
    57. break;
    58. }
    59. //新建一个bmp图片
    60. System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
    61. //新建一个画板
    62. System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
    63. //设置高质量插值法
    64. g.InterpolationMode = interpolationMode ;
    65. //设置高质量,低速度呈现平滑程度
    66. g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
    67. //清空画布并以透明背景色填充
    68. g.Clear(System.Drawing.Color.Transparent);
    69. //在指定位置并且按指定大小绘制原图片的指定部分
    70. g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight),
    71. new System.Drawing.Rectangle(x, y, ow, oh),
    72. System.Drawing.GraphicsUnit.Pixel);
    73. try
    74. {
    75. //以jpg格式保存缩略图
    76. System.IO.MemoryStream mstream = new System.IO.MemoryStream();
    77. System.Drawing.Imaging.ImageFormat format = originalImage.RawFormat;
    78. System.Drawing.Imaging.ImageFormat toFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
    79. if (format.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
    80. {
    81. toFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
    82. }
    83. else if (format.Equals(System.Drawing.Imaging.ImageFormat.Png))
    84. {
    85. toFormat = System.Drawing.Imaging.ImageFormat.Png;
    86. }
    87. else if (format.Equals(System.Drawing.Imaging.ImageFormat.Bmp))
    88. {
    89. toFormat = System.Drawing.Imaging.ImageFormat.Bmp;
    90. }
    91. else if (format.Equals(System.Drawing.Imaging.ImageFormat.Gif))
    92. {
    93. toFormat = System.Drawing.Imaging.ImageFormat.Gif;
    94. }
    95. else if (format.Equals(System.Drawing.Imaging.ImageFormat.Icon))
    96. {
    97. toFormat = System.Drawing.Imaging.ImageFormat.Icon;
    98. }
    99. else if (format.Equals(System.Drawing.Imaging.ImageFormat.Emf))
    100. {
    101. toFormat = System.Drawing.Imaging.ImageFormat.Emf;
    102. }
    103. else if (format.Equals(System.Drawing.Imaging.ImageFormat.Exif))
    104. {
    105. toFormat = System.Drawing.Imaging.ImageFormat.Exif;
    106. }
    107. else if (format.Equals(System.Drawing.Imaging.ImageFormat.Tiff))
    108. {
    109. toFormat = System.Drawing.Imaging.ImageFormat.Tiff;
    110. }
    111. else if (format.Equals(System.Drawing.Imaging.ImageFormat.Wmf))
    112. {
    113. toFormat = System.Drawing.Imaging.ImageFormat.Wmf;
    114. }
    115. bitmap.Save(mstream, toFormat);
    116. byte[] byData = new Byte[mstream.Length];
    117. mstream.Position = 0;
    118. mstream.Read(byData, 0, byData.Length);
    119. mstream.Close();
    120. if (thumbnailPath != "")
    121. {
    122. bitmap.Save(thumbnailPath, toFormat);
    123. }
    124. return byData;
    125. }
    126. catch (System.Exception e)
    127. {
    128. throw e;
    129. }
    130. finally
    131. {
    132. originalImage.Dispose();
    133. bitmap.Dispose();
    134. g.Dispose();
    135. }
    136. }

    调用示例

    本调用示例实现判断上传的图像大小,如果图像大于2Mb则自动进行压缩处理。

    1. string upfilename = Request.PhysicalApplicationPath + "\\upload.jpg"; //上传的图片路径
    2. string mtfilename = Request.PhysicalApplicationPath + "\\mt.jpg"; //缩略图的图片路径
    3. if (System.IO.File.Exists(upfilename))
    4. {
    5. FileInfo fileInfo = new FileInfo(upfilename);
    6. float _fsize = fileInfo.Length / (1024*1024);
    7. if (_fsize >= 2)
    8. {
    9. MakeThumbnail(upfilename, null, mtfilename);
    10. }
    11. else
    12. {
    13. mtfilename = upfilename;
    14. }
    15. Response.Write("Result Filename is :"+mtfilename);
    16. }

    小结

    输出缩略图可以采取动态输出和静态存储方式,动态输出耗性能,静态存储耗空间,我们可以以空间换时间来获取更高的性能。我们需要根据项目的实际情况来决定采用哪种方式比较平衡。

    感谢您的阅读,希望本文能够对您有所帮助。  

  • 相关阅读:
    ES6----箭头函数
    JAVA毕业设计101—基于Java+Springboot的电影购票微信小程序带后台管理(源码+数据库)
    AUTOSAR跨网络的CAN报文路由的实现
    使用 Neo4j 图数据库可视化(网络安全)知识图谱
    Notion 类笔记软件如何选择?Notion 、FlowUs、Wolai 对比评测
    Python 解决tkinter的Menu菜单command参数与bind方法共用触发事件
    化工园区数字孪生可视化管控平台,赋予园区安全环保智慧发展
    人工电销时代,你来不来 ,ai智能电话机器人
    深入探索JVM高效并发 — Java内存模型(二)
    Java 继承详解
  • 原文地址:https://blog.csdn.net/michaelline/article/details/137965481