天天看點

.NET5生成gif縮略圖

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

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

        /// <summary>
        /// 生成縮略圖,針對GIF圖檔
        /// </summary>
        /// <param name="imgPath">輸入檔案位址</param>
        /// <param name="savePath">儲存檔案位址</param>
        /// <param name="width">壓縮輸出寬度</param>
        /// <param name="height">壓縮輸出高度</param>
        public static void GifYasuo(string imgPath, string savePath, int width, int height)
        {
            //原圖
            Image img = Image.FromFile(imgPath);
            //不夠100*100的不縮放
            if (img.Width > 100 && img.Height > 100)
            {
                //按比例縮放            
                if (img.Width > width)
                {
                    height = width * img.Height / img.Width;
                }

                //新圖第一幀
                Image new_img = new Bitmap(width, height);
                //新圖其他幀
                Image new_imgs = new Bitmap(width, height);
                //新圖第一幀GDI+繪圖對象
                Graphics g_new_img = Graphics.FromImage(new_img);
                //新圖其他幀GDI+繪圖對象
                Graphics g_new_imgs = Graphics.FromImage(new_imgs);
                //配置新圖第一幀GDI+繪圖對象
                g_new_img.CompositingMode = CompositingMode.SourceCopy;
                g_new_img.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g_new_img.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g_new_img.SmoothingMode = SmoothingMode.HighQuality;
                g_new_img.Clear(Color.FromKnownColor(KnownColor.Transparent));
                //配置其他幀GDI+繪圖對象
                g_new_imgs.CompositingMode = CompositingMode.SourceCopy;
                g_new_imgs.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g_new_imgs.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g_new_imgs.SmoothingMode = SmoothingMode.HighQuality;
                g_new_imgs.Clear(Color.FromKnownColor(KnownColor.Transparent));

                品質設定
                //EncoderParameters qualityEncoder = new EncoderParameters(1);
                //long[] qy = new long[1];
                //qy[0] = flag;//設定壓縮的比例1-100  
                //var ep_quality = new EncoderParameter(Encoder.Quality, qy);
                //qualityEncoder.Param[0] = ep_quality;

                //周遊維數
                foreach (Guid gid in img.FrameDimensionsList)
                {
                    //因為是縮小GIF檔案是以這裡要設定為Time
                    //如果是TIFF這裡要設定為PAGE
                    FrameDimension f = FrameDimension.Time;
                    //擷取總幀數
                    int count = img.GetFrameCount(f);
                    //儲存标示參數
                    Encoder encoder = Encoder.SaveFlag;
                    //
                    EncoderParameters ep = null;
                    //圖檔編碼、解碼器
                    ImageCodecInfo ici = null;
                    //圖檔編碼、解碼器集合
                    ImageCodecInfo[] icis = ImageCodecInfo.GetImageDecoders();
                    //為 圖檔編碼、解碼器 對象 指派
                    foreach (ImageCodecInfo ic in icis)
                    {
                        if (ic.FormatID == ImageFormat.Gif.Guid)
                        {
                            ici = ic;
                            break;
                        }
                    }
                    //每一幀
                    for (int c = 0; c < count; c++)
                    {
                        //選擇由次元和索引指定的幀
                        img.SelectActiveFrame(f, c);
                        //第一幀
                        if (c == 0)
                        {
                            //将原圖第一幀畫給新圖第一幀
                            g_new_img.DrawImage(img, new Rectangle(0, 0, width, height), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
                            //把振頻和透明背景調色闆等設定複制給新圖第一幀
                            for (int i = 0; i < img.PropertyItems.Length; i++)
                            {
                                new_img.SetPropertyItem(img.PropertyItems[i]);
                            }
                            ep = new EncoderParameters(1);
                            //第一幀需要設定為MultiFrame
                            ep.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);
                            //ep.Param[1] = eParam;
                            //儲存第一幀
                            new_img.Save(savePath, ici, ep);
                        }
                        //其他幀
                        else
                        {
                            //把原圖的其他幀畫給新圖的其他幀
                            g_new_imgs.DrawImage(img, new Rectangle(0, 0, width, height), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
                            //把振頻和透明背景調色闆等設定複制給新圖第一幀
                            for (int i = 0; i < img.PropertyItems.Length; i++)
                            {
                                new_imgs.SetPropertyItem(img.PropertyItems[i]);
                            }
                            ep = new EncoderParameters(1);
                            //如果是GIF這裡設定為FrameDimensionTime
                            //如果為TIFF則設定為FrameDimensionPage                           
                            ep.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionTime);

                            //向新圖添加一幀
                            new_img.SaveAdd(new_imgs, ep);

                            //whl添加,設定儲存品質
                            //new_img.SaveAdd(qualityEncoder);
                        }
                    }
                    ep = new EncoderParameters(1);
                    //關閉多幀檔案流
                    ep.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush);
                    new_img.SaveAdd(ep);
                }

                //whl添加,設定儲存品質
                //圖檔編碼、解碼器
                ImageCodecInfo ici2 = null;
                //圖檔編碼、解碼器集合
                ImageCodecInfo[] icis2 = ImageCodecInfo.GetImageDecoders();
                //為 圖檔編碼、解碼器 對象 指派
                foreach (ImageCodecInfo ic in icis2)
                {
                    if (ic.FormatID == ImageFormat.Gif.Guid)
                    {
                        ici2 = ic;
                        break;
                    }
                }
                //釋放檔案
                img.Dispose();
                new_img.Dispose();
                new_imgs.Dispose();
                g_new_img.Dispose();
                g_new_imgs.Dispose();
            }

        }