private Bitmap EncodeGif <T>(Color backgrnd, int minAlpha, int startIndex, int frameCount) where T : GifEncoder { //预判大小 Rectangle rect = this.GetRect(); Bitmap canvas = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb); string tempFileName = Path.GetTempFileName(); GifEncoder enc = (GifEncoder)Activator.CreateInstance(typeof(T), tempFileName, rect.Width, rect.Height); //写入帧信息 for (int i = startIndex, j = startIndex + frameCount; i < j; i++) { if (i >= this.Frames.Count) { break; } IGifFrame frame = this.Frames[i]; if (frame == null) { continue; } PrepareFrame(canvas, frame, rect, backgrnd, minAlpha); enc.AppendFrame(canvas, frame.Delay); } enc.Dispose(); return(Image.FromFile(tempFileName) as Bitmap); }
private static Bitmap PrepareFrame(IGifFrame frame, Rectangle canvasRect, Color backgrnd, int minAlpha) { Bitmap gifFrame = new Bitmap(canvasRect.Width, canvasRect.Height, PixelFormat.Format32bppArgb); PrepareFrame(gifFrame, frame, canvasRect, backgrnd, minAlpha); return(gifFrame); }
/// <summary> /// 预处理帧坐标,生成新的图片。 /// </summary> private static void PrepareFrame(Bitmap canvas, IGifFrame frame, Rectangle canvasRect, Color backgrnd, int minAlpha) { Graphics g = Graphics.FromImage(canvas); if (backgrnd.A == 0xff) //背景色 { g.Clear(backgrnd); frame.Draw(g, canvasRect); } else //透明混合色 { g.Clear(Color.Transparent); Rectangle frameRect = frame.Region; frameRect.Offset(-canvasRect.X, -canvasRect.Y); frame.Draw(g, canvasRect); BitmapData data = canvas.LockBits(new Rectangle(Point.Empty, canvas.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); unsafe { byte *buffer = (byte *)data.Scan0.ToPointer(); for (int y = frameRect.Top; y < frameRect.Bottom; y++) { for (int x = frameRect.Left; x < frameRect.Right; x++) { int i = 4 * x + y * data.Stride; byte a = buffer[i + 3]; if (a <= minAlpha) { buffer[i] = buffer[i + 1] = buffer[i + 2] = buffer[i + 3] = 0; } else if (a < 0xff) { float al = a / 255f; float be = (1 - al); buffer[i] = (byte)(buffer[i] * al + backgrnd.B * be); buffer[i + 1] = (byte)(buffer[i + 1] * al + backgrnd.G * be); buffer[i + 2] = (byte)(buffer[i + 2] * al + backgrnd.R * be); buffer[i + 3] = 0xff; } } } } canvas.UnlockBits(data); } }