/// <summary> /// 从文件流中读取应用程序扩展块 /// </summary> /// <param name="stream"></param> /// <returns></returns> internal ApplicationEx GetApplicationEx(Stream stream) { ApplicationEx appEx = new ApplicationEx(); int blockSize = Read(); if (blockSize != ApplicationEx.BlockSize) { throw new Exception("数据格式错误!"); } appEx.ApplicationIdentifier = ReadChar(8); appEx.ApplicationAuthenticationCode = ReadChar(3); int nextFlag = Read(); appEx.Datas = new List <DataStruct>(); while (nextFlag != 0) { DataStruct data = new DataStruct(nextFlag, stream); appEx.Datas.Add(data); nextFlag = Read(); } return(appEx); }
/// <summary> /// 合并多个gif动画,在空间坐标上 /// </summary> /// <param name="sourceGifs">原图像</param> /// <param name="outPath">合并后图像</param> public void Merge(List <string> sourceGifs, string outPath) { List <List <GifFrame> > frames = new List <List <GifFrame> >(); 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 gifImage = GifDecoder.Decode(source); ThinkDisposalMethod(gifImage); int index = 0; foreach (GifFrame f in gifImage.Frames) { if (frames.Count <= index) { List <GifFrame> list = new List <GifFrame>(); frames.Add(list); } List <GifFrame> frameList = frames[index]; frameList.Add(f); index++; } } List <GifFrame> frameCol = new List <GifFrame>(); int frameIndex = 0; foreach (List <GifFrame> fs in frames) { GifFrame frame = Merge(fs); frameCol.Add(frame); if (frame.Image.Width != frameCol[0].Image.Width || frame.Image.Height != frameCol[0].Image.Height) { frame.ImageDescriptor.XOffSet = frames[frameIndex][0].ImageDescriptor.XOffSet; frame.ImageDescriptor.YOffSet = frames[frameIndex][0].ImageDescriptor.YOffSet; frame.GraphicExtension.DisposalMethod = frames[frameIndex][0].GraphicExtension.DisposalMethod; } frame.GraphicExtension.Delay = frame.Delay = frames[frameIndex][0].Delay; frameIndex++; } GifImage gifImg = new GifImage(); gifImg.Header = "GIF89a"; LogicalScreenDescriptor lcd = new LogicalScreenDescriptor(); lcd.Width = (short)frameCol[0].Image.Width; lcd.Height = (short)frameCol[0].Image.Height; gifImg.LogicalScreenDescriptor = lcd; ApplicationEx ape = new ApplicationEx(); List <ApplicationEx> apps = new List <ApplicationEx>(); apps.Add(ape); gifImg.ApplictionExtensions = apps; gifImg.Frames = frameCol; GifEncoder.Encode(gifImg, outPath); }
/// <summary> /// 对gif图像文件进行解码 /// </summary> /// <param name="gifPath">gif文件路径</param> internal static GifImage Decode(string gifPath) { FileStream fs = null; StreamHelper streamHelper = null; GifImage gifImage = new GifImage(); List <GraphicEx> graphics = new List <GraphicEx>(); int frameCount = 0; try { fs = new FileStream(gifPath, FileMode.Open); streamHelper = new StreamHelper(fs); //读取文件头 gifImage.Header = streamHelper.ReadString(6); //读取逻辑屏幕标示符 gifImage.LogicalScreenDescriptor = streamHelper.GetLCD(fs); if (gifImage.LogicalScreenDescriptor.GlobalColorTableFlag) { //读取全局颜色列表 gifImage.GlobalColorTable = streamHelper.ReadByte(gifImage.LogicalScreenDescriptor.GlobalColorTableSize * 3); } int nextFlag = streamHelper.Read(); while (nextFlag != 0) { if (nextFlag == GifExtensions.ImageLabel) { ReadImage(streamHelper, fs, gifImage, graphics, frameCount); frameCount++; } else if (nextFlag == GifExtensions.ExtensionIntroducer) { int gcl = streamHelper.Read(); switch (gcl) { case GifExtensions.GraphicControlLabel: { GraphicEx graphicEx = streamHelper.GetGraphicControlExtension(fs); graphics.Add(graphicEx); break; } case GifExtensions.CommentLabel: { CommentEx comment = streamHelper.GetCommentEx(fs); gifImage.CommentExtensions.Add(comment); break; } case GifExtensions.ApplicationExtensionLabel: { ApplicationEx applicationEx = streamHelper.GetApplicationEx(fs); gifImage.ApplictionExtensions.Add(applicationEx); break; } case GifExtensions.PlainTextLabel: { PlainTextEx textEx = streamHelper.GetPlainTextEx(fs); gifImage.PlainTextEntensions.Add(textEx); break; } } } else if (nextFlag == GifExtensions.EndIntroducer) { //到了文件尾 break; } nextFlag = streamHelper.Read(); } } catch { throw; } finally { fs.Close(); } return(gifImage); }
/// <summary> /// 合并多个gif文件 /// </summary> /// <param name="sourceGifs">原图像路径集合</param> /// <param name="outGif">合并后图像路径</param> /// <param name="delay">间隔时间</param> /// <param name="repeat">是否重复播放</param> public 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) { f.Delay = f.GraphicExtension.Delay = lastDelay; } if (f.Delay == 0) { f.Delay = f.GraphicExtension.Delay = lastDelay; } f.ColorDepth = (byte)(Math.Log(f.ImageDescriptor.LctSize, 2)); lastDelay = f.GraphicExtension.Delay; frameCount++; } gifImage.Frames.AddRange(gif.Frames); index++; } if (repeat && gifImage.ApplictionExtensions.Count == 0) { ApplicationEx ae = new ApplicationEx(); gifImage.ApplictionExtensions.Add(ae); } gifImage.LogicalScreenDescriptor.PixcelAspect = 0; Size maxSize = FindMaxSize(sourceGifs); gifImage.LogicalScreenDescriptor.Width = (short)maxSize.Width; gifImage.LogicalScreenDescriptor.Height = (short)maxSize.Height; GifEncoder.Encode(gifImage, outGif); }