123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- using Microsoft.Extensions.Configuration;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Text;
- namespace Bowin.Common.Files
- {
- public static class ImgHelper
- {
- private static FileSettings Settings { get; set; }
- static ImgHelper()
- {
- var configuration = new ConfigurationBuilder()
- .SetBasePath(Directory.GetCurrentDirectory())
- .AddJsonFile("appsettings.json")
- .Build();
- Settings = configuration.GetSection("FileSettings").Get<FileSettings>();
- }
- //解析base64编码获取图片
- public static Image Base64ToImg(string base64Code)
- {
- MemoryStream stream = new MemoryStream(Convert.FromBase64String(base64Code));
- var img = new Bitmap(stream);
- var len = (stream.Length / 1024) / 1024;
- if (len >= 1)
- {
- var zipImg = ImgHelper.ZipImage(img, ImgHelper.GetImageFormat(img), 1024);
- return zipImg;
- }
- return img;
- }
- /// <summary>
- /// 无损压缩图片
- /// </summary>
- /// <param name="sFile">原图片地址</param>
- /// <param name="dFile">压缩后保存图片地址</param>
- /// <param name="flag">压缩质量(数字越小压缩率越高)1-100</param>
- /// <param name="size">压缩后图片的最大大小</param>
- /// <param name="sfsc">是否是第一次调用</param>
- /// <returns></returns>
- public static bool CompressImage(string sFile, string dFile, int flag = 90, int size = 300, bool sfsc = true)
- {
- //如果是第一次调用,原始图像的大小小于要压缩的大小,则直接复制文件,并且返回true
- FileInfo firstFileInfo = new FileInfo(sFile);
- if (sfsc == true && firstFileInfo.Length < size * 1024)
- {
- firstFileInfo.CopyTo(dFile);
- return true;
- }
- Image iSource = Image.FromFile(sFile);
- ImageFormat tFormat = iSource.RawFormat;
- int dHeight = iSource.Height / 2;
- int dWidth = iSource.Width / 2;
- int sW = 0, sH = 0;
- //按比例缩放
- Size tem_size = new Size(iSource.Width, iSource.Height);
- if (tem_size.Width > dHeight || tem_size.Width > dWidth)
- {
- if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
- {
- sW = dWidth;
- sH = (dWidth * tem_size.Height) / tem_size.Width;
- }
- else
- {
- sH = dHeight;
- sW = (tem_size.Width * dHeight) / tem_size.Height;
- }
- }
- else
- {
- sW = tem_size.Width;
- sH = tem_size.Height;
- }
- Bitmap ob = new Bitmap(dWidth, dHeight);
- Graphics g = Graphics.FromImage(ob);
- g.Clear(Color.WhiteSmoke);
- g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
- g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
- g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
- g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);
- g.Dispose();
- //以下代码为保存图片时,设置压缩质量
- EncoderParameters ep = new EncoderParameters();
- long[] qy = new long[1];
- qy[0] = flag;//设置压缩的比例1-100
- EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
- ep.Param[0] = eParam;
- try
- {
- ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
- ImageCodecInfo jpegICIinfo = null;
- for (int x = 0; x < arrayICI.Length; x++)
- {
- if (arrayICI[x].FormatDescription.Equals("JPEG"))
- {
- jpegICIinfo = arrayICI[x];
- break;
- }
- }
- if (jpegICIinfo != null)
- {
- ob.Save(dFile, jpegICIinfo, ep);//dFile是压缩后的新路径
- FileInfo fi = new FileInfo(dFile);
- if (fi.Length > 1024 * size)
- {
- flag = flag - 10;
- CompressImage(sFile, dFile, flag, size, false);
- }
- }
- else
- {
- ob.Save(dFile, tFormat);
- }
- return true;
- }
- catch
- {
- return false;
- }
- finally
- {
- iSource.Dispose();
- ob.Dispose();
- }
- }
- /// <summary>
- /// 指定压缩尺寸
- /// </summary>
- /// <param name="bitmap"></param>
- /// <param name="destHeight"></param>
- /// <param name="destWidth"></param>
- /// <returns></returns>
- public static Image ZoomImage(Image bitmap, int destHeight, int destWidth)
- {
- try
- {
- System.Drawing.Image sourImage = bitmap;
- int width = 0, height = 0;
- //按比例缩放
- int sourWidth = sourImage.Width;
- int sourHeight = sourImage.Height;
- if (sourHeight > destHeight || sourWidth > destWidth)
- {
- if ((sourWidth * destHeight) > (sourHeight * destWidth))
- {
- width = destWidth;
- height = (destWidth * sourHeight) / sourWidth;
- }
- else
- {
- height = destHeight;
- width = (sourWidth * destHeight) / sourHeight;
- }
- }
- else
- {
- width = sourWidth;
- height = sourHeight;
- }
- Bitmap destBitmap = new Bitmap(destWidth, destHeight);
- Graphics g = Graphics.FromImage(destBitmap);
- g.Clear(Color.Transparent);
- //设置画布的描绘质量
- g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
- g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
- g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
- g.DrawImage(sourImage, new Rectangle((destWidth - width) / 2, (destHeight - height) / 2, width, height), 0, 0, sourImage.Width, sourImage.Height, GraphicsUnit.Pixel);
- //g.DrawImage(sourImage, new Rectangle(0, 0, destWidth, destHeight), new Rectangle(0, 0, sourImage.Width, sourImage.Height), GraphicsUnit.Pixel);
- g.Dispose();
- //设置压缩质量
- System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
- long[] quality = new long[1];
- quality[0] = 100;
- System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
- encoderParams.Param[0] = encoderParam;
- sourImage.Dispose();
- return destBitmap;
- }
- catch (Exception ex)
- {
- return bitmap;
- }
- }
- /// <summary>
- /// 压缩图片至200 Kb以下
- /// </summary>
- /// <param name="img">图片</param>
- /// <param name="format">图片格式</param>
- /// <param name="targetLen">压缩后大小</param>
- /// <param name="srcLen">原始大小</param>
- /// <returns>压缩后的图片</returns>
- public static Image ZipImage(Image img, ImageFormat format, long targetLen, long srcLen = 0)
- {
- //设置大小偏差幅度 10kb
- const long nearlyLen = 10240;
- //内存流 如果参数中原图大小没有传递 则使用内存流读取
- var ms = new MemoryStream();
- if (0 == srcLen)
- {
- img.Save(ms, format);
- srcLen = ms.Length;
- }
- //单位 由Kb转为byte 若目标大小高于原图大小,则满足条件退出
- targetLen *= 1024;
- if (targetLen > srcLen)
- {
- ms.SetLength(0);
- ms.Position = 0;
- img.Save(ms, format);
- img = Image.FromStream(ms);
- return img;
- }
- //获取目标大小最低值
- var exitLen = targetLen - nearlyLen;
- //初始化质量压缩参数 图像 内存流等
- var quality = (long)Math.Floor(100.00 * targetLen / srcLen);
- var parms = new EncoderParameters(1);
- //获取编码器信息
- ImageCodecInfo formatInfo = null;
- var encoders = ImageCodecInfo.GetImageEncoders();
- foreach (ImageCodecInfo icf in encoders)
- {
- if (icf.FormatID == format.Guid)
- {
- formatInfo = icf;
- break;
- }
- }
- //使用二分法进行查找 最接近的质量参数
- long startQuality = quality;
- long endQuality = 100;
- quality = (startQuality + endQuality) / 2;
- while (true)
- {
- //设置质量
- parms.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
- //清空内存流 然后保存图片
- ms.SetLength(0);
- ms.Position = 0;
- img.Save(ms, formatInfo, parms);
- //若压缩后大小低于目标大小,则满足条件退出
- if (ms.Length >= exitLen && ms.Length <= targetLen)
- {
- break;
- }
- else if (startQuality >= endQuality) //区间相等无需再次计算
- {
- break;
- }
- else if (ms.Length < exitLen) //压缩过小,起始质量右移
- {
- startQuality = quality;
- }
- else //压缩过大 终止质量左移
- {
- endQuality = quality;
- }
- //重新设置质量参数 如果计算出来的质量没有发生变化,则终止查找。这样是为了避免重复计算情况{start:16,end:18} 和 {start:16,endQuality:17}
- var newQuality = (startQuality + endQuality) / 2;
- if (newQuality == quality)
- {
- break;
- }
- quality = newQuality;
- //Console.WriteLine("start:{0} end:{1} current:{2}", startQuality, endQuality, quality);
- }
- img = Image.FromStream(ms);
- return img;
- }
- /// <summary>
- ///获取图片格式
- /// </summary>
- /// <param name="img">图片</param>
- /// <returns>默认返回JPEG</returns>
- public static ImageFormat GetImageFormat(Image img)
- {
- if (img.RawFormat.Equals(ImageFormat.Jpeg))
- {
- return ImageFormat.Jpeg;
- }
- if (img.RawFormat.Equals(ImageFormat.Gif))
- {
- return ImageFormat.Gif;
- }
- if (img.RawFormat.Equals(ImageFormat.Png))
- {
- return ImageFormat.Png;
- }
- if (img.RawFormat.Equals(ImageFormat.Bmp))
- {
- return ImageFormat.Bmp;
- }
- return ImageFormat.Jpeg;//根据实际情况选择返回指定格式还是null
- }
- }
- }
|