.NET 实现GIF 图片的裁剪

【相关类库】 链接: http://pan.baidu.com/s/1gd9XfBt 密码: h27c

参考链接:

http://www.codeproject.com/Articles/11505/NGif-Animated-GIF-Encoder-for-NET

http://cnn237111.blog.51cto.com/2359144/1261422


折腾了一些时间,NGIF不可以直接使用,会有各种各样的问题,合成的图片有黑线条等等不如意的问题。留言下面有很多网友的留言国内国外都有,还有针对上面做出修改的版本。经过一番研究再加上相关资源整合了一下,终于可以满足我的基本需求了。其他不做赘述了,该说的其他人都说了.

具体实现原理,先把gif 图片一帧一帧拆分成jpg图片,然后针对每个图片进行裁剪,局部裁剪还是等比裁剪等等可以自己实现网上有很多针对jpge图片的处理类,我这里也提供了一个Thumbnail.cs类可下载.

实现部分

  private static Size gifSize;
        private static int delay;
        /// <summary>
        /// 裁剪GIF图片
        /// </summary>
        /// <param name="gifFilePath">源文件地址</param>
        /// <param name="maxWidth">最大宽度</param>
        /// <param name="maxHeight">最大高度</param>
        /// <param name="outputPath">输出文件地址</param>
        public static void GetThumbnail(string gifFilePath, int maxWidth, int maxHeight, string outputPath)
        {
            List<Image> gifList = GetFrames(gifFilePath);
            AnimatedGifEncoder ae = new AnimatedGifEncoder();
            ae.Start();
            ae.SetDelay(delay);    // 延迟间隔
            ae.SetRepeat(0);  //-1:不循环,0:总是循环 播放  
            //我这里是等比缩小(如果原图长大于宽以长为基准缩放,反之以宽为基准缩放)
            Size _newSize = Thumbnail.ResizeImage(gifSize.Width, gifSize.Height, maxWidth, maxHeight);
            ae.SetSize(_newSize.Width,_newSize.Height);
            for (int i = 0, count = gifList.Count; i < count; i++)
            {
                //Image frame = Image.FromFile(gifList[i]);
                ae.AddFrame(gifList[i]);
            }
            ae.Finish();
            ae.Output(outputPath);
        }

        //解码gif图片
        public static List<Image> GetFrames(string pPath)
        {
            Image gif = Image.FromFile(pPath);
            gifSize = new Size(gif.Width, gif.Height);
            FrameDimension fd = new FrameDimension(gif.FrameDimensionsList[0]);
            //获取帧数(gif图片可能包含多帧,其它格式图片一般仅一帧)
            int count = gif.GetFrameCount(fd);
           // List<string> gifList = new List<string>();
            List<Image> gifList = new List<Image>();
            //以Jpeg格式保存各帧
            for (int i = 0; i < count; i++)
            {
                gif.SelectActiveFrame(fd, i);
                //获取第一帧 的延时时间。/*-----说明一下,按道理应该每一帧的延时时间都应该获取,在合并的时候再设置delay,但是我测试很多图片的每一帧之间的延时时间都是一样的------*/
                if (i == 0)
                {
                    for (int j = 0; j < gif.PropertyIdList.Length; j++)//遍历帧属性
                    {
                        if ((int)gif.PropertyIdList.GetValue(j) == 0x5100)//.如果是延迟时间
                        {
                            PropertyItem pItem = (PropertyItem)gif.PropertyItems.GetValue(j);//获取延迟时间属性
                            byte[] delayByte = new byte[4];//延迟时间,以1/100秒为单位
                            delayByte[0] = pItem.Value[i * 4];
                            delayByte[1] = pItem.Value[1 + i * 4];
                            delayByte[2] = pItem.Value[2 + i * 4];
                            delayByte[3] = pItem.Value[3 + i * 4];
                            delay = BitConverter.ToInt32(delayByte, 0) * 10; //乘以10,获取到毫秒
                            break;
                        }
                    }
                }
                gifList.Add( new Bitmap(gif));//这里可以将每帧图片保存成文件gif.save(,);根据需求
            }
            gif.Dispose();
            return gifList;
        }

说明:

AnimatedGifEncoder.cs  -> GetImagePixels()

protected void GetImagePixels() 
		{
			int w = image.Width;
			int h = image.Height;
			//		int type = image.GetType().;
			if ((w != width)
				|| (h != height)
				) 
			{
				// create new image with right size/format
				Image temp = new Bitmap(width, height );
                Graphics g = Graphics.FromImage(temp);
                // 设置画布的描绘质量,说明:这里是等比缩放,可以根据需求从Thumbnail.cs中找到符合自己的缩放方法进行修改。
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(image, new Rectangle(0, 0, width, height), 0, 0, w, h, GraphicsUnit.Pixel);
				image = temp;
				g.Dispose();
			}
			/*
				ToDo:
				improve performance: use unsafe code 
			*/
			pixels = new Byte [ 3 * image.Width * image.Height ];
			int count = 0;
			Bitmap tempBitmap = new Bitmap( image );
			for (int th = 0; th < image.Height; th++)
			{
				for (int tw = 0; tw < image.Width; tw++)
				{
					Color color = tempBitmap.GetPixel(tw, th);
					pixels[count] = color.R;
					count++;
					pixels[count] = color.G;
					count++;
					pixels[count] = color.B;
					count++;
				}
			}
            tempBitmap.Dispose();
            image.Dispose();
			//		pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
		}


转载于:https://my.oschina.net/chengkuan/blog/297236

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值