📄 gifhelper.cs
字号:
}
#region 对图像进行量化,使其适应调色板
/// <summary>
/// 对图像进行量化,使其适应调色板
/// </summary>
/// <param name="bmp">图像</param>
/// <param name="colorTab">调色板</param>
static void Quantizer(Bitmap bmp, Color32[] colorTab)
{
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
Hashtable table = new Hashtable();
unsafe
{
int* bmpScan = (int*)bmpData.Scan0.ToPointer();
for (int i = 0; i < bmp.Height * bmp.Width; i++)
{
Color c = Color.FromArgb(bmpScan[i]);
int rc = FindCloser(c, colorTab, table);
Color newc = Color.FromArgb(rc);
bmpScan[i] = rc;
}
}
bmp.UnlockBits(bmpData);
}
/// <summary>
/// 对图像进行量化,使其适应调色板
/// </summary>
/// <param name="bmp">图像</param>
/// <param name="colorTab">调色板</param>
static void Quantizer(Bitmap bmp, int[] colorTab)
{
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
Hashtable table = new Hashtable();
unsafe
{
int* bmpScan = (int*)bmpData.Scan0.ToPointer();
for (int i = 0; i < bmp.Height * bmp.Width; i++)
{
Color c = Color.FromArgb(bmpScan[i]);
int rc = FindCloser(c, colorTab, table);
Color newc = Color.FromArgb(rc);
bmpScan[i] = rc;
}
}
bmp.UnlockBits(bmpData);
}
static int FindCloser(Color c, Color32[] act, Hashtable table)
{
if (table.Contains(c))
{
return ((Color32)table[c]).ARGB;
}
int index = 0;
int min = 0;
int minIndex = 0;
while (index < act.Length)
{
Color ac = act[index].Color;
int tempIndex = index;
int cr = Math.Abs(c.R - ac.R);
int cg = Math.Abs(c.G - ac.G);
int cb = Math.Abs(c.B - ac.B);
int ca = Math.Abs(c.A - ac.A);
int result = cr + cg + cb + ca;
if (result == 0)
{
minIndex = tempIndex;
break;
}
if (tempIndex == 0)
{
min = result;
}
else
{
if (result < min)
{
min = result;
minIndex = tempIndex;
}
}
index++;
}
if (!table.Contains(c))
{
table.Add(c, act[minIndex]);
}
return act[minIndex].ARGB;
}
static int FindCloser(Color c, int[] act, Hashtable table)
{
if (table.Contains(c))
{
return Convert.ToInt32(table[c]);
}
int index = 0;
int min = 0;
int minIndex = 0;
while (index < act.Length)
{
Color ac = Color.FromArgb(act[index]);
int tempIndex = index;
int cr = Math.Abs(c.R - ac.R);
int cg = Math.Abs(c.G - ac.G);
int cb = Math.Abs(c.B - ac.B);
int ca = Math.Abs(c.A - ac.A);
int result = cr + cg + cb + ca;
if (result == 0)
{
minIndex = tempIndex;
break;
}
if (tempIndex == 0)
{
min = result;
}
else
{
if (result < min)
{
min = result;
minIndex = tempIndex;
}
}
index++;
}
if (!table.Contains(c))
{
table.Add(c, act[minIndex]);
}
return act[minIndex];
}
#endregion
#endregion
#region Gif动画单色化
/// <summary>
/// Gif动画单色化
/// </summary>
/// <param name="gifFilePath">原动画路径</param>
/// <param name="outputPath">单色后动画路径</param>
public static void Monochrome(string gifFilePath, 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);
int transIndex = gifImage.LogicalScreenDescriptor.BgColorIndex;
int c1 = (255 << 24) | (158 << 16) | (128 << 8) | 128;
int c2 = (255 << 24) | (0 << 16) | (0 << 8) | 0;
int c3 = (255 << 24) | (255 << 16) | (255 << 8) | 255;
int c4 = (255 << 24) | (0 << 16) | (0 << 8) | 0;
int[] palette = new int[] { c1, c2, c3, c4 };
byte[] buffer = new byte[12] { 128, 128, 128, 0, 0, 0, 255, 255, 255, 0, 0, 0 };
gifImage.GlobalColorTable = buffer;
gifImage.LogicalScreenDescriptor.BgColorIndex = 0;
gifImage.LogicalScreenDescriptor.GlobalColorTableSize = 4;
gifImage.LogicalScreenDescriptor.GlobalColorTableFlag = true;
int index = 0;
foreach (GifFrame f in gifImage.Frames)
{
Color32[] act = PaletteHelper.GetColor32s(f.LocalColorTable);
f.LocalColorTable = buffer;
Color bgC = act[(transIndex / 3)].Color;
byte bgGray = (byte)(bgC.R * 0.3 + bgC.G * 0.59 + bgC.B * 0.11);
BitmapData bmpData = f.Image.LockBits(new Rectangle(0, 0, f.Image.Width, f.Image.Height), ImageLockMode.ReadWrite, f.Image.PixelFormat);
unsafe
{
int* p = (int*)bmpData.Scan0.ToPointer();
for (int i = 0; i < f.Image.Width * f.Image.Height; i++)
{
if (p[i] == 0)
{
p[i] = c1;
}
else
{
Color c = Color.FromArgb(p[i]);
int gray = (byte)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
if (gray > bgGray)
{
if (bgGray > 128)
{
p[i] = c2;
}
else
{
p[i] = c3;
}
}
else if (gray < bgGray)
{
if (bgGray > 128)
{
p[i] = c3;
}
else
{
p[i] = c2;
}
}
else
{
p[i] = c1;
}
}
}
}
f.Image.UnlockBits(bmpData);
f.GraphicExtension.TranIndex = 0;
f.ColorDepth = 2;
f.ImageDescriptor.LctFlag = false;
index++;
}
GifEncoder.Encode(gifImage, outputPath);
}
#endregion
#region 合并多个gif动画,在时间坐标上
static Size FindMaxSize(List<string> sources)
{
List<int> widths = new List<int>();
List<int> heights = new List<int>();
foreach (string s in sources)
{
Bitmap bmp = new Bitmap(s);
widths.Add(bmp.Width);
heights.Add(bmp.Height);
bmp.Dispose();
}
widths.Sort();
heights.Sort();
return new Size(widths[widths.Count - 1], heights[heights.Count - 1]);
}
/// <summary>
/// 合并多个gif文件
/// </summary>
/// <param name="sourceGifs">原图像路径集合</param>
/// <param name="outGif">合并后图像路径</param>
/// <param name="delay">间隔时间</param>
/// <param name="repeat">是否重复播放</param>
public static 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -