You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C#代码为现有GIF图片添加底部文字与背景并保存

问题:C#实现给GIF底部添加文字并保存

我有如下原始图片:
Gif Image
我希望通过代码编辑该GIF,在其底部添加文字,使文字成为GIF图片的一部分。

预期效果示例如下:
我用红色标注了想要添加到第一张图的灰色背景和时间日期文字,就是示例中灰色区域加文字的效果。
Marked in red at the bottom to show what I mean by adding the gray background and the text.

我想要给第一张GIF添加底部的日期时间文字,可以仅加文字,也可以新增底部灰色像素背景区域后再写入文字,最终保存修改后的GIF。
上述第二张图只是我想要在第一张图上实现的效果示例,具体文字内容可以自定义,核心需求是可编辑GIF、在底部添加文字并保存修改后的GIF。


目前已尝试的代码

新建了如下代码的类:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.Text;

namespace Wpf_Download_Files
{
    class DrawOnImage
    {
        public Image DrawText(String text, String subText, Image img)
        {
            var textColor = Color.Black;
            var backColor = Color.Transparent;

            var textFont = new Font("Arial", 15);
            Brush textBrush = new SolidBrush(textColor);

            var subTextFont = new Font("Arial", 7);
            Brush subTextBrush = new SolidBrush(textColor);

            //first, create a dummy bitmap just to get a graphics object
            img = new Bitmap(img);
            Graphics drawing = Graphics.FromImage(img);

            //measure the string to see how big the image needs to be
            SizeF textSize = drawing.MeasureString(text, textFont);
            SizeF subTextSize = drawing.MeasureString(subText, subTextFont);

            //free up the dummy image and old graphics object
            img.Dispose();
            drawing.Dispose();

            //create a new image of the right size
            img = new Bitmap(((int)textSize.Width + (int)subTextSize.Width) - ((int)textSize.Width / 3), (int)textSize.Height + 15);

            drawing = Graphics.FromImage(img);
            drawing.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;

            //paint the background
            drawing.Clear(backColor);

            //Draw Text
            drawing.DrawString(text, textFont, textBrush, 5, 0);

            //Drawing Line
            var linePen = new Pen(Color.Black, 3);
            var height = (int)textSize.Height;
            var width = (int)textSize.Width;

            drawVerticalLine(drawing, linePen, 1, 0, height + 5);
            drawHorizontalLine(drawing, linePen, 0, height + 5, width / 3);

            //Darw Subtext
            drawing.DrawString(subText, subTextFont, subTextBrush, width / 3, height);

            drawing.Save();

            textBrush.Dispose();
            drawing.Dispose();

            return img;
        }

        private void drawHorizontalLine(Graphics graphics, Pen pen, int x, int y, int width)
        {
            graphics.DrawLine(pen, x, y, x + width, y);
        }

        private void drawVerticalLine(Graphics graphics, Pen pen, int x, int y, int height)
        {
            graphics.DrawLine(pen, x, y, x, y + height);
        }
    }
}

主窗体调用代码如下:

public MainWindow()
{
    InitializeComponent();

    System.Drawing.Image img =
        System.Drawing.Image.FromFile(@"d:\Downloaded Images\Image0.gif");
    DrawOnImage drawonimage = new DrawOnImage();
    drawonimage.DrawText("Hello World", "utt 12345", img);
}

运行后GIF底部没有添加任何背景和文字,需要解决该问题实现需求。


解决方案

现有代码的核心问题

  1. 逻辑错误:你拿到原始GIF后先创建了副本,计算完文字尺寸就直接释放了原始GIF,最后返回的是仅包含文字的全新小图,完全没有保留原始GIF的内容。
  2. 未处理动帧:GIF是多帧动图,默认的System.Drawing.Image只能加载第一帧,就算修改了单帧,保存后也会丢失动效。
  3. 没有保存结果:你调用完DrawText方法后没有保存返回的图片,原始GIF文件当然不会有任何变化。

正确实现方案

我们需要先拆分GIF的所有帧,给每帧底部加上灰色背景和文字,再重新编码为动图保存,以下是可直接运行的实现:

  1. 先安装NuGet包:Magick.NET-Q16-AnyCPU
  2. 替换原有实现类:
using ImageMagick;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

public class GifEditor
{
    public void AddTextToGif(string inputGifPath, string outputGifPath, string mainText, string subText)
    {
        // 加载GIF所有帧
        using var collection = new MagickImageCollection(inputGifPath);
        var firstFrame = collection[0];
        int gifWidth = firstFrame.Width;
        int textAreaHeight = 40; // 底部文字区域高度
        int newGifHeight = firstFrame.Height + textAreaHeight;

        // 预渲染文字区域,避免每帧重复计算
        using var textBitmap = new Bitmap(gifWidth, textAreaHeight);
        using (var g = Graphics.FromImage(textBitmap))
        {
            g.Clear(Color.LightGray); // 灰色背景
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            var mainFont = new Font("Arial", 14, FontStyle.Bold);
            var subFont = new Font("Arial", 9);
            var blackBrush = Brushes.Black;

            // 文字居中绘制
            var mainSize = g.MeasureString(mainText, mainFont);
            g.DrawString(mainText, mainFont, blackBrush, (gifWidth - mainSize.Width)/2, 3);

            var subSize = g.MeasureString(subText, subFont);
            g.DrawString(subText, subFont, blackBrush, (gifWidth - subSize.Width)/2, 22);
        }
        // 把文字区域转成MagickImage格式
        using var textLayer = MagickImage.FromBitmap(textBitmap);

        // 遍历所有帧处理
        foreach (var frame in collection)
        {
            // 扩展画布,底部留出文字区域
            frame.Extent(gifWidth, newGifHeight, Gravity.North, MagickColors.Transparent);
            // 把文字区域合成到帧底部
            frame.Composite(textLayer, 0, frame.Height - textAreaHeight, CompositeOperator.Over);
        }

        // 保存为动图
        collection.Write(outputGifPath);
    }
}
  1. 调用方式修改为:
public MainWindow()
{
    InitializeComponent();

    var editor = new GifEditor();
    editor.AddTextToGif(@"d:\Downloaded Images\Image0.gif", 
        @"d:\Downloaded Images\Image0_with_text.gif", 
        "2024-05-20 14:30", 
        "自定义备注文字");
}

注意事项

  • 如果你用的是.NET Framework,不需要安装System.Drawing.Common,直接引用System.Drawing即可
  • 生成的新GIF会保存在你指定的输出路径,不会修改原始文件
  • 文字大小、区域高度、背景色都可以根据需求自行调整参数

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:06:05