⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gifhelper.cs

📁 gif图像处理 包括对多帧gif动画的缩放
💻 CS
📖 第 1 页 / 共 3 页
字号:
        }

        #region 对图像进行量化,使其适应调色板
        /// <summary>
        /// 对图像进行量化,使其适应调色板
        /// </summary>
        /// <param name="bmp">图像</param>
        /// <param name="colorTab">调色板</param>
        static void Quantizer(Bitmap bmp, Color32[] colorTab)
        {
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
            Hashtable table = new Hashtable();
            unsafe
            {
                int* bmpScan = (int*)bmpData.Scan0.ToPointer();
                for (int i = 0; i < bmp.Height * bmp.Width; i++)
                {
                    Color c = Color.FromArgb(bmpScan[i]);
                    int rc = FindCloser(c, colorTab, table);
                    Color newc = Color.FromArgb(rc);
                    bmpScan[i] = rc;
                }
            }
            bmp.UnlockBits(bmpData);
        }
        /// <summary>
        /// 对图像进行量化,使其适应调色板
        /// </summary>
        /// <param name="bmp">图像</param>
        /// <param name="colorTab">调色板</param>
        static void Quantizer(Bitmap bmp, int[] colorTab)
        {
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
            Hashtable table = new Hashtable();
            unsafe
            {
                int* bmpScan = (int*)bmpData.Scan0.ToPointer();
                for (int i = 0; i < bmp.Height * bmp.Width; i++)
                {
                    Color c = Color.FromArgb(bmpScan[i]);
                    int rc = FindCloser(c, colorTab, table);
                    Color newc = Color.FromArgb(rc);
                    bmpScan[i] = rc;
                }
            }
            bmp.UnlockBits(bmpData);
        }
        static int FindCloser(Color c, Color32[] act, Hashtable table)
        {
            if (table.Contains(c))
            {
                return ((Color32)table[c]).ARGB;
            }
            int index = 0;
            int min = 0;
            int minIndex = 0;
            while (index < act.Length)
            {
                Color ac = act[index].Color;
                int tempIndex = index;
                int cr = Math.Abs(c.R - ac.R);
                int cg = Math.Abs(c.G - ac.G);
                int cb = Math.Abs(c.B - ac.B);
                int ca = Math.Abs(c.A - ac.A);
                int result = cr + cg + cb + ca;
                if (result == 0)
                {
                    minIndex = tempIndex;
                    break;
                }
                if (tempIndex == 0)
                {
                    min = result;
                }
                else
                {
                    if (result < min)
                    {
                        min = result;
                        minIndex = tempIndex;
                    }
                }
                index++;
            }
            if (!table.Contains(c))
            {
                table.Add(c, act[minIndex]);
            }
            return act[minIndex].ARGB;
        }
        static int FindCloser(Color c, int[] act, Hashtable table)
        {
            if (table.Contains(c))
            {
                return Convert.ToInt32(table[c]);
            }
            int index = 0;
            int min = 0;
            int minIndex = 0;
            while (index < act.Length)
            {
                Color ac = Color.FromArgb(act[index]);
                int tempIndex = index;
                int cr = Math.Abs(c.R - ac.R);
                int cg = Math.Abs(c.G - ac.G);
                int cb = Math.Abs(c.B - ac.B);
                int ca = Math.Abs(c.A - ac.A);
                int result = cr + cg + cb + ca;
                if (result == 0)
                {
                    minIndex = tempIndex;
                    break;
                }
                if (tempIndex == 0)
                {
                    min = result;
                }
                else
                {
                    if (result < min)
                    {
                        min = result;
                        minIndex = tempIndex;
                    }
                }
                index++;
            }
            if (!table.Contains(c))
            {
                table.Add(c, act[minIndex]);
            }
            return act[minIndex];
        }
        #endregion

        #endregion

        #region Gif动画单色化
        /// <summary>
        /// Gif动画单色化
        /// </summary>
        /// <param name="gifFilePath">原动画路径</param>
        /// <param name="outputPath">单色后动画路径</param>
        public static void Monochrome(string gifFilePath, string outputPath)
        {
            if (!File.Exists(gifFilePath))
            {
                throw new IOException(string.Format("文件{0}不存在!", gifFilePath));
            }
            using (Bitmap ora_Img = new Bitmap(gifFilePath))
            {
                if (ora_Img.RawFormat.Guid != ImageFormat.Gif.Guid)
                {
                    throw new IOException(string.Format("文件{0}!", gifFilePath));
                }
            }
            GifImage gifImage = GifDecoder.Decode(gifFilePath);
            int transIndex = gifImage.LogicalScreenDescriptor.BgColorIndex;
            int c1 = (255 << 24) | (158 << 16) | (128 << 8) | 128;
            int c2 = (255 << 24) | (0 << 16) | (0 << 8) | 0;
            int c3 = (255 << 24) | (255 << 16) | (255 << 8) | 255;
            int c4 = (255 << 24) | (0 << 16) | (0 << 8) | 0;
            int[] palette = new int[] { c1, c2, c3, c4 };
            byte[] buffer = new byte[12] { 128, 128, 128, 0, 0, 0, 255, 255, 255, 0, 0, 0 };
            gifImage.GlobalColorTable = buffer;
            gifImage.LogicalScreenDescriptor.BgColorIndex = 0;
            gifImage.LogicalScreenDescriptor.GlobalColorTableSize = 4;
            gifImage.LogicalScreenDescriptor.GlobalColorTableFlag = true;
            int index = 0;
            foreach (GifFrame f in gifImage.Frames)
            {
                Color32[] act = PaletteHelper.GetColor32s(f.LocalColorTable);
                f.LocalColorTable = buffer;
                Color bgC = act[(transIndex / 3)].Color;
                byte bgGray = (byte)(bgC.R * 0.3 + bgC.G * 0.59 + bgC.B * 0.11);
                BitmapData bmpData = f.Image.LockBits(new Rectangle(0, 0, f.Image.Width, f.Image.Height), ImageLockMode.ReadWrite, f.Image.PixelFormat);
                unsafe
                {
                    int* p = (int*)bmpData.Scan0.ToPointer();
                    for (int i = 0; i < f.Image.Width * f.Image.Height; i++)
                    {
                        if (p[i] == 0)
                        {
                            p[i] = c1;

                        }
                        else
                        {
                            Color c = Color.FromArgb(p[i]);
                            int gray = (byte)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
                            if (gray > bgGray)
                            {
                                if (bgGray > 128)
                                {
                                    p[i] = c2;
                                }
                                else
                                {
                                    p[i] = c3;
                                }
                            }
                            else if (gray < bgGray)
                            {
                                if (bgGray > 128)
                                {
                                    p[i] = c3;
                                }
                                else
                                {
                                    p[i] = c2;
                                }
                            }
                            else
                            {
                                p[i] = c1;
                            }
                        }
                    }
                }
                f.Image.UnlockBits(bmpData);
                f.GraphicExtension.TranIndex = 0;
                f.ColorDepth = 2;
                f.ImageDescriptor.LctFlag = false;
                index++;
            }
            GifEncoder.Encode(gifImage, outputPath);
        }
        #endregion

        #region 合并多个gif动画,在时间坐标上
        static Size FindMaxSize(List<string> sources)
        {
            List<int> widths = new List<int>();
            List<int> heights = new List<int>();
            foreach (string s in sources)
            {
                Bitmap bmp = new Bitmap(s);
                widths.Add(bmp.Width);
                heights.Add(bmp.Height);
                bmp.Dispose();
            }
            widths.Sort();
            heights.Sort();
            return new Size(widths[widths.Count - 1], heights[heights.Count - 1]);
        }

        /// <summary>
        /// 合并多个gif文件
        /// </summary>
        /// <param name="sourceGifs">原图像路径集合</param>
        /// <param name="outGif">合并后图像路径</param>
        /// <param name="delay">间隔时间</param>
        /// <param name="repeat">是否重复播放</param> 
        public static void Merge(List<string> sourceGifs, string outGif, short delay, bool repeat)
        {
            GifImage gifImage = null;
            int index = 0;
            short lastDelay = delay;
            foreach (string source in sourceGifs)
            {
                if (!File.Exists(source))
                {
                    throw new IOException(string.Format("文件{0}不存在!", source));
                }
                using (Bitmap ora_Img = new Bitmap(source))
                {
                    if (ora_Img.RawFormat.Guid != ImageFormat.Gif.Guid)
                    {
                        throw new IOException(string.Format("文件{0}!", source));
                    }
                }
                GifImage gif = GifDecoder.Decode(source);
                if (index == 0)
                {
                    gifImage = gif;
                }
                int frameCount = 0;
                foreach (GifFrame f in gif.Frames)
                {
                    if (frameCount == 0 && f.GraphicExtension.DisposalMethod == 0)
                    {
                        f.GraphicExtension.DisposalMethod = 2;
                    }
                    if (!f.ImageDescriptor.LctFlag)
                    {
                        f.ImageDescriptor.LctSize = f.LocalColorTable.Length / 3;
                        f.ImageDescriptor.LctFlag = true;
                        f.GraphicExtension.TranIndex = gif.LogicalScreenDescriptor.BgColorIndex;
                        f.LocalColorTable = gif.GlobalColorTable;
                    }
                    if (frameCount == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -