码迷,mamicode.com
首页 > Web开发 > 详细

.NET 实现GIF 图片的裁剪

时间:2014-08-01 20:26:02      阅读:361      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   strong   io   

【相关类库】 链接: 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();
		}


.NET 实现GIF 图片的裁剪,布布扣,bubuko.com

.NET 实现GIF 图片的裁剪

标签:style   blog   http   color   使用   os   strong   io   

原文地址:http://my.oschina.net/chengkuan/blog/297236

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!