C#中基于GDI+(Graphics)图像处理系列之高质量缩略图
来源:互联网 发布:公司淘宝店注册流程 编辑:程序博客网 时间:2024/06/14 03:47
简介
生成图片缩略图的功能在Web开发的工作是经常遇到的,比如用户上传一张图片作为用户头像,根据业务的需要生成若干不同尺寸的缩略图,不同的功能使用不同尺寸的图片等等。
大家知道Image类有一个GetThumbnailImage的方法来生成缩略图,但是这货表现得非常不稳定,笔者就曾经掉了它的坑中被狠狠地坑了一把,所以决定自己实现生成缩略图的功能。
本文将重点向大家介绍怎么使用GDI+(Graphics)实现生成缩略图功能,同时提醒大家要想获得高质量的缩略图需要做的设置。
动手前先解决两个问题
获取高质量的Graphics
/// <summary> /// 获取高清的Graphics /// </summary> /// <param name="img"></param> /// <returns></returns> public Graphics GetGraphics(Image img) { var g = Graphics.FromImage(img); //设置质量 g.SmoothingMode = SmoothingMode.HighQuality; g.CompositingQuality = CompositingQuality.HighQuality; //InterpolationMode不能使用High或者HighQualityBicubic,如果是灰色或者部分浅色的图像是会在边缘处出一白色透明的线 //用HighQualityBilinear却会使图片比其他两种模式模糊(需要肉眼仔细对比才可以看出) g.InterpolationMode = InterpolationMode.Default; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; return g;}
注意InterpolationMode的值为Default,之前我在设置这个值的时候,毫不犹豫的选择了High,在实际项目中发现,对于灰色的图片,会在图片边缘由于插值会画上透明的白线,采用HighQualityBicubic也会有类似的情况;而使用HighQualityBilinear,图片会比其他几种模糊,当然,这种模糊要有好的显示器和对比才能看出来,请仔细对比下面三张图片。
保存Image时进一步控制质量
通常我们在保存图片时使用下面的代码,这种方法就是将图片直接保存成jpeg格式,不能进一步控制质量,仔细观察,在笔触边缘有虚化的现象。
//方法1image. .Save("1.jpg", ImageFormat.Jpeg);
我推荐采用下面的方法
//方法2/// <summary>/// 将Image实例保存到文件,注意此方法不执行 img.Dispose()/// 图片保存时本可以直接使用destImage.Save(path, ImageFormat.Jpeg),但是这种方法无法进行进一步控制图片质量/// </summary>/// <param name="path"></param>/// <param name="img"></param>/// <param name="quality">1~100整数,无效值,则取默认值95</param>/// <param name="mimeType"></param>public void SaveImage2File(string path, Image destImage, int quality, string mimeType = "image/jpeg"){ if (quality <= 0 || quality > 100) quality = 95; //创建保存的文件夹 FileInfo fileInfo = new FileInfo(path); if (!Directory.Exists(fileInfo.DirectoryName)) { Directory.CreateDirectory(fileInfo.DirectoryName); } //设置保存参数,保存参数里进一步控制质量 EncoderParameters encoderParams = new EncoderParameters(); long[] qua = new long[] { quality }; EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); encoderParams.Param[0] = encoderParam; //获取指定mimeType的mimeType的ImageCodecInfo var codecInfo = ImageCodecInfo.GetImageEncoders().FirstOrDefault(ici => ici.MimeType == mimeType); destImage.Save(path, codecInfo, encoderParams); }
使用时传入quality值(1~100),我个人认为95已经很好了,93足够,如采用方法1生成的图片效果跟第二种方法quality=70生成的效果差不多。
生成高质量的缩略图
下面是生成全部源码,代码中的详细的注释,这里不再赘述
/// <summary>/// 生成高质量缩略图(固定宽高),不一定保持原宽高比/// </summary>/// <param name="destPath">目标保存路径</param>/// <param name="srcPath">源文件路径</param>/// <param name="width">生成缩略图的宽度,设置为0,则与源图比处理</param>/// <param name="height">生成缩略图的高度,设置为0,则与源图等比例处理</param>/// <param name="quality">1~100整数,无效值则取默认值95</param>/// <param name="mimeType">如 image/jpeg</param> public bool GetThumbnailImage(string destPath, string srcPath, int destWidth, int destHeight, int quality, out string error, string mimeType = "image/jpeg"){ bool retVal = false; error = string.Empty; //宽高不能小于0 if (destWidth < 0 || destHeight < 0) { error = "目标宽高不能小于0"; return retVal; } //宽高不能同时为0 if (destWidth == 0 && destHeight == 0) { error = "目标宽高不能同时为0"; return retVal; } Image srcImage = null; Image destImage = null; Graphics graphics = null; try { //获取源图像 srcImage = Image.FromFile(srcPath, false); //计算高宽比例 float d = (float)srcImage.Height / srcImage.Width; //如果输入的宽为0,则按高度等比缩放 if (destWidth == 0) { destWidth = Convert.ToInt32(destHeight / d); } //如果输入的高为0,则按宽度等比缩放 if (destHeight == 0) { destHeight = Convert.ToInt32(destWidth * d); } //定义画布 destImage = new Bitmap(destWidth, destHeight); //获取高清Graphics graphics = GetGraphics(destImage); //将源图像画到画布上,注意最后一个参数GraphicsUnit.Pixel graphics.DrawImage(srcImage, new Rectangle(0, 0, destWidth, destHeight), new Rectangle(0, 0, srcImage.Width, srcImage.Height), GraphicsUnit.Pixel); //如果是覆盖则先释放源资源 if (destPath == srcPath) { srcImage.Dispose(); } //保存到文件,同时进一步控制质量 SaveImage2File(destPath, destImage, quality, mimeType); retVal = true; } catch (Exception ex) { error = ex.Message; } finally { if (srcImage != null) srcImage.Dispose(); if (destImage != null) destImage.Dispose(); if (graphics != null) graphics.Dispose(); } return retVal;}
完整示例程序源码
http://download.csdn.net/detail/lhtzbj12/9730116
示例程序截图
如果想查阅本系列其他文章,请移步《C#中基于GDI+(Graphics)图像处理系列之前言》
- C#中基于GDI+(Graphics)图像处理系列之高质量缩略图
- C#中基于GDI+(Graphics)图像处理系列之前言
- C#中基于GDI+(Graphics)图像处理系列之任意角度旋转图像
- C#中基于GDI+(Graphics)图像处理系列之图片压缩优化
- C#中基于GDI+(Graphics)图像处理系列之文字或者图片水印(透明、任意角度旋转)
- C#中基于GDI+(Graphics)图像处理系列之UEditor上传图片自动压缩优化(添加水印)
- C#高质量缩略图
- c# 生成高质量缩略图
- C#生成高质量缩略图
- C# 生成高质量缩略图
- C# 生成高质量缩略图
- c#生成高质量缩略图
- 利用 Graphics 的 DrawImage 生成高质量的缩略图。
- C# 生成高质量缩略图程序
- C#的图片处理类,生成高质量缩略图,代码已测试过,效果很好
- C#处理图像-缩略图,图像翻转
- 图像处理之基于高斯金字塔的图像融合
- 生成高质量缩略图
- java垃圾收集描述
- C/C++生成随机数字符串(错误方法和正确方法)
- LeetCode -- Count of Smaller Numbers After Self
- linux学习笔记--uname命令
- lunx学习笔记一 liunx基本知识
- C#中基于GDI+(Graphics)图像处理系列之高质量缩略图
- 微信小程序_仿淘宝
- 上传和下载
- Allegro 快捷键设置
- 《Ansible_Up-And-Running》笔记2-Ansible实战
- 简述spring 的事务传播行为和 隔离级别
- Android EditText回车不换行
- Android ViewDragHelper及移动处理总结
- php 解决json gbk编码中文null问题