天天看點

.net5生成圖檔縮略圖,有旋轉的縮略圖生成回正圖檔

需要在nuget安裝包System.Drawing.Common

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WebNetCore5_Img_Storage.Model.Tool
{
    /// <summary>
    /// 生成圖檔縮略圖
    /// </summary>
    /// <remarks>
    /// 建立時間:2021-2-5 16:32:19
    /// </remarks>
    public static class ImageHandle
    {
        /// <summary>
        /// (推薦)生成縮略圖,圖檔流輸入,輸出圖檔流
        /// </summary>
        /// <param name="dWidth">要生成的寬度</param>
        /// <param name="dHeight">要生成的高度</param>
        /// <param name="flag">生成圖檔品質,1-100</param>
        /// <param name="inputStream">輸入圖檔流</param>
        /// <param name="outStream">輸出圖檔流</param>
        public static void CompressImgByte(int dWidth, int dHeight, Stream inputStream, Stream outStream, int flag = 80, string arg = null)
        {
            System.Drawing.Image iSource = System.Drawing.Image.FromStream(inputStream);
            var prop = iSource.PropertyItems.FirstOrDefault(x => x.Id == 274);
            if (prop != null)
            {
                //讀取旋轉方向
                byte[] buffed = prop.Value;
                StringBuilder sbv = new StringBuilder();
                foreach (var byteValue in buffed)
                {
                    sbv.Append(byteValue.ToString("x2"));
                }             
                string value2 = sbv.ToString();
                //Console.WriteLine($"圖檔id  {arg}  圖檔274裡面的值>" + value2);//linux測試
                //windows擷取到旋轉的值為0600,linux旋轉值為0006
                if (value2.Equals("0006") || value2.Equals("0600"))
                {
                    //未做任何操作,此縮略圖會自動逆時針旋轉90度
                    //下面操作糾正旋轉,讓其順時針旋轉90度,讓圖檔回正
                    iSource.RotateFlip(RotateFlipType.Rotate90FlipNone);
                }
            }

            System.Drawing.Imaging.ImageFormat tFormat = iSource.RawFormat;
            //按比例縮放            
            if (dWidth > 0 && iSource.Width > dWidth && iSource.Width > iSource.Height)
            {
                dHeight = dWidth * iSource.Height / iSource.Width;
            }
            else if (dWidth > 0 && dHeight == 0 && iSource.Width > dWidth)
            {
                dHeight = dWidth * iSource.Height / iSource.Width;
            }
            else if (dWidth == 0 && dHeight > 0 && iSource.Width > iSource.Height)
            {
                dWidth = dHeight * iSource.Width / iSource.Height;
            }
            else if (dHeight > iSource.Height || dWidth > iSource.Width)
            {
                dWidth = iSource.Width;
                dHeight = iSource.Height;
            }
            else if (dHeight > 0 && iSource.Width < iSource.Height)
            {
                dWidth = dHeight * iSource.Width / iSource.Height;
            }
            else
            {
                dWidth = iSource.Width;
                dHeight = iSource.Height;
            }

            Bitmap ob = new Bitmap(dWidth, dHeight);
            //ob.SetResolution(72,72);
            Graphics g = Graphics.FromImage(ob);
            //清空畫布并以透明背景色填充
            g.Clear(System.Drawing.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(iSource, new Rectangle(0, 0, dWidth, dHeight), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);
            g.Dispose();
            //以下代碼為儲存圖檔時,設定壓縮品質  
            System.Drawing.Imaging.EncoderParameters ep = new System.Drawing.Imaging.EncoderParameters();
            long[] qy = new long[1];
            qy[0] = flag;//設定壓縮的比例1-100  
            System.Drawing.Imaging.EncoderParameter eParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
            ep.Param[0] = eParam;
            try
            {
                System.Drawing.Imaging.ImageCodecInfo[] arrayICI = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
                System.Drawing.Imaging.ImageCodecInfo jpegICIinfo = arrayICI.FirstOrDefault(x => x.FormatDescription.Equals("JPEG"));
                if (jpegICIinfo != null)
                {
                    //ob.Save("d://" + DateTime.Now.Ticks + ".jpg", jpegICIinfo, ep);
                    ob.Save(outStream, jpegICIinfo, ep);//dFile是壓縮後的新路徑
                }
                else
                {
                    ob.Save(outStream, tFormat);
                }
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
                Console.WriteLine(msg);
            }
            finally
            {
                iSource.Dispose();
                ob.Dispose();
            }
        }

        /// <summary>
        /// (推薦)生成縮略圖,圖檔流輸入,輸出圖檔流
        /// </summary>
        /// <param name="dWidth">要生成的寬度</param>
        /// <param name="dHeight">要生成的高度</param>
        /// <param name="filePath">輸入檔案路徑</param>
        /// <param name="outFilePath">輸出儲存檔案路徑</param>
        /// <param name="flag">生成的圖檔品質,0-100,預設80</param>
        public static void CompressImgFile(int dWidth, int dHeight, string filePath, string outFilePath, int flag = 80)
        {
            System.Drawing.Image iSource = System.Drawing.Image.FromFile(filePath);
            //檢測圖檔是否有旋轉
            foreach (var item in iSource.PropertyItems)
            {
                //System.Diagnostics.Debug.WriteLine(item.Id);
                if (item.Id == 274)
                {
                    //讀取旋轉方向
                    byte[] buffed = item.Value;
                    StringBuilder sbv = new StringBuilder();
                    foreach (var byteValue in buffed)
                    {
                        sbv.Append(byteValue.ToString("x2"));
                    }
                    //string value2 = string.Join("", buffed);
                    string value2 = sbv.ToString();
                    System.Diagnostics.Debug.WriteLine("方向=" + value2);
                    //windows擷取到旋轉的值為0600,linux旋轉值為0006
                    if (value2.Equals("0006") || value2.Equals("0600"))
                    {
                        //未做任何操作,此縮略圖會自動逆時針旋轉90度
                        //下面操作糾正旋轉,讓其順時針旋轉90度,讓圖檔回正
                        iSource.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    }
                    break;
                }
            }

            System.Drawing.Imaging.ImageFormat tFormat = iSource.RawFormat;
            //按比例縮放            
            if (dWidth > 0 && iSource.Width > dWidth && iSource.Width > iSource.Height)
            {
                dHeight = dWidth * iSource.Height / iSource.Width;
            }
            else if (dWidth > 0 && dHeight == 0 && iSource.Width > dWidth)
            {
                dHeight = dWidth * iSource.Height / iSource.Width;
            }
            else if (dWidth == 0 && dHeight > 0 && iSource.Width > iSource.Height)
            {
                dWidth = dHeight * iSource.Width / iSource.Height;
            }
            else if (dHeight > iSource.Height || dWidth > iSource.Width)
            {
                dWidth = iSource.Width;
                dHeight = iSource.Height;
            }
            else if (dHeight > 0 && iSource.Width < iSource.Height)
            {
                dWidth = dHeight * iSource.Width / iSource.Height;
            }
            else
            {
                dWidth = iSource.Width;
                dHeight = iSource.Height;
            }

            Bitmap ob = new Bitmap(dWidth, dHeight);
            //ob.SetResolution(72,72);
            Graphics g = Graphics.FromImage(ob);
            //清空畫布并以透明背景色填充
            g.Clear(System.Drawing.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(iSource, new Rectangle(0, 0, dWidth, dHeight), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);
            g.Dispose();
            //以下代碼為儲存圖檔時,設定壓縮品質  
            System.Drawing.Imaging.EncoderParameters ep = new System.Drawing.Imaging.EncoderParameters();
            long[] qy = new long[1];
            qy[0] = flag;//設定壓縮的比例1-100  
            System.Drawing.Imaging.EncoderParameter eParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
            ep.Param[0] = eParam;
            try
            {
                System.Drawing.Imaging.ImageCodecInfo[] arrayICI = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
                System.Drawing.Imaging.ImageCodecInfo jpegICIinfo = null;
                // string imgExtend = tFormat.ToString().ToUpper();
                string imgExtend = "JPEG";
                for (int x = 0; x < arrayICI.Length; x++)
                {
                    if (arrayICI[x].FormatDescription.Equals(imgExtend))
                    {
                        jpegICIinfo = arrayICI[x];
                        break;
                    }
                }
                if (jpegICIinfo != null)
                {
                    ob.Save(outFilePath, jpegICIinfo, ep);//dFile是壓縮後的新路徑  
                }
                else
                {
                    ob.Save(outFilePath, tFormat);
                }
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
                Console.WriteLine(msg);
            }
            finally
            {
                iSource.Dispose();
                ob.Dispose();
            }
        }
 

    }
}