应用场景
我们假设会有如下场景:
场景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,两者同时传递以物理路径文件优先。
实现代码
方法代码
//制作缩略图(压缩图),可接收两种参数,物理路径文件 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则自动进行压缩处理。
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); }
小结
输出缩略图可以采取动态输出和静态存储方式,动态输出耗性能,静态存储耗空间,我们可以以空间换时间来获取更高的性能。我们需要根据项目的实际情况来决定采用哪种方式比较平衡。
到此这篇关于c#实现生成指定图片的缩略图的文章就介绍到这了,更多相关c#生成图片缩略图内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论