📄 gifhelper.cs
字号:
{
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);
}
#endregion
#region 合并多个gif动画,在空间坐标上
/// <summary>
/// 合并多个gif动画,在空间坐标上
/// </summary>
/// <param name="sourceGifs">原图像</param>
/// <param name="outPath">合并后图像</param>
public static 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);
}
#endregion
#region 将Gif图片进行旋转或者翻转
/// <summary>
/// 将Gif图片进行旋转或者翻转
/// </summary>
/// <param name="gifFilePath">原图像路径</param>
/// <param name="rotateType">翻转或者旋转方式</param>
/// <param name="outputPath">输出路径</param>
public static void Rotate(string gifFilePath, RotateFlipType rotateType, 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);
ThinkDisposalMethod(gifImage);
int index = 0;
foreach (GifFrame f in gifImage.Frames)
{
f.Image.RotateFlip(rotateType);
f.ImageDescriptor.Width = (short)f.Image.Width;
f.ImageDescriptor.Height = (short)f.Image.Height;
if (index++ == 0)
{
gifImage.LogicalScreenDescriptor.Width = (short)f.Image.Width;
gifImage.LogicalScreenDescriptor.Height = (short)f.Image.Height;
}
}
GifEncoder.Encode(gifImage, outputPath);
}
#endregion
#region 对Gif图片进行剪裁
/// <summary>
/// 对Gif图片进行剪裁
/// </summary>
/// <param name="gifFilePath">原图像</param>
/// <param name="rect">剪裁区域</param>
/// <param name="outFilePath">输出路径</param>
public static void Crop(string gifFilePath, Rectangle rect, string outFilePath)
{
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);
ThinkDisposalMethod(gifImage);
int index = 0;
foreach (GifFrame f in gifImage.Frames)
{
f.Image = f.Image.Clone(rect, f.Image.PixelFormat);
f.ImageDescriptor.Width = (short)rect.Width;
f.ImageDescriptor.Height = (short)rect.Height;
if (index++ == 0)
{
gifImage.LogicalScreenDescriptor.Width = (short)rect.Width;
gifImage.LogicalScreenDescriptor.Height = (short)rect.Height;
}
}
GifEncoder.Encode(gifImage, outFilePath);
}
#endregion
#region 私有方法
static void ThinkDisposalMethod(GifImage gifImage)
{
int lastDisposal = 0;
Bitmap lastImage = null;
int index = 0;
short width = gifImage.Width;
short height = gifImage.Height;
foreach (GifFrame f in gifImage.Frames)
{
int xOffSet = f.ImageDescriptor.XOffSet;
int yOffSet = f.ImageDescriptor.YOffSet;
int iw = f.ImageDescriptor.Width;
int ih = f.ImageDescriptor.Height;
if ((f.Image.Width != width || f.Image.Height != height))
{
f.ImageDescriptor.XOffSet = 0;
f.ImageDescriptor.YOffSet = 0;
f.ImageDescriptor.Width = (short)width;
f.ImageDescriptor.Height = (short)height;
}
int transIndex = -1;
if (f.GraphicExtension.TransparencyFlag)
{
transIndex = f.GraphicExtension.TranIndex;
}
if (iw == width && ih == height && index == 0)
{
}
else
{
int bgColor = Convert.ToInt32(gifImage.GlobalColorIndexedTable[f.GraphicExtension.TranIndex]);
Color c = Color.FromArgb(bgColor);
Bitmap newImg = null;
Graphics g;
newImg = new Bitmap(width, height);
g = Graphics.FromImage(newImg);
if (lastImage != null)
{
g.DrawImageUnscaled(lastImage, new Point(0, 0));
}
if (f.GraphicExtension.DisposalMethod == 1)
{
g.DrawRectangle(new Pen(new SolidBrush(c)), new Rectangle(xOffSet, yOffSet, iw, ih));
}
if (f.GraphicExtension.DisposalMethod == 2 && lastDisposal != 1)
{
g.Clear(c);
}
g.DrawImageUnscaled(f.Image, new Point(xOffSet, yOffSet));
g.Dispose();
f.Image.Dispose();
f.Image = newImg;
}
lastImage = f.Image;
Quantizer(f.Image, f.Palette);
lastDisposal = f.GraphicExtension.DisposalMethod;
index++;
}
}
static GifFrame Merge(List<GifFrame> frames)
{
Bitmap bmp = null;
Graphics g = null;
foreach (GifFrame f in frames)
{
if (bmp == null)
{
bmp = f.Image;
g = Graphics.FromImage(bmp);
}
else
{
g.DrawImageUnscaled(f.Image, new Point(f.ImageDescriptor.XOffSet, f.ImageDescriptor.YOffSet));
}
}
if (g != null)
{
g.Dispose();
}
GifFrame frame = new GifFrame();
Color32[] pellatte = new OcTreeQuantizer(8).Quantizer(bmp);
Quantizer(bmp, pellatte);
frame.Image = bmp;
frame.LocalColorTable = GetColorTable(pellatte);
frame.ImageDescriptor = new ImageDescriptor();
frame.ImageDescriptor.LctFlag = true;
frame.ImageDescriptor.LctSize = pellatte.Length;
frame.ImageDescriptor.Width = (short)bmp.Width;
frame.ImageDescriptor.Height = (short)bmp.Height;
frame.ColorDepth = 8;
frame.GraphicExtension = new GraphicEx();
frame.GraphicExtension.DisposalMethod = 0;
frame.GraphicExtension.TransparencyFlag = true;
frame.GraphicExtension.TranIndex = 255;
return frame;
}
static byte[] GetColorTable(Color32[] pellatte)
{
byte[] buffer = new byte[pellatte.Length * 3];
int index = 0;
for (int i = 0; i < pellatte.Length; i++)
{
buffer[index++] = pellatte[i].Red;
buffer[index++] = pellatte[i].Green;
buffer[index++] = pellatte[i].Blue;
}
return buffer;
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -