.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(); }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。