本文主要介绍.NET(C#)中,使用GDI+(Graphics)绘图的方法,将文字和logo图内容生成视频封面图片的方法,以及相关示例代码。

实现代码:

public void ConvertTextFileToImage(string title, string content, string logoPath, string imageFile)
{
    Bitmap newBitmap = null;
    Graphics g = null;
    try
    {
        Font titleFont = new Font("宋体", 50);
        Font contentFont = new Font("宋体", 30);
        newBitmap = new Bitmap(1920, 1080, PixelFormat.Format32bppArgb);
        using (var logoFile = Image.FromFile(logoPath))//logo图片
        {
            g = Graphics.FromImage(newBitmap);
            int rowHeight = (int)(Math.Ceiling(g.MeasureString("位置", titleFont).Height));
            Rectangle recangleTitle = new Rectangle(0, 0, 1920, rowHeight);
            //标题
            DrawStringTitle(g, titleFont, title, recangleTitle, logoFile.Height + 100);
            //描述内容
            Rectangle recangle = new Rectangle(0, 0, 1920, 1080 - rowHeight);
            DrawStringWrap(g, contentFont, content, recangle, rowHeight + logoFile.Height + 200);
            //logo图片
            g.DrawImage(logoFile, new Rectangle((1920 - logoFile.Width) / 2, 30, logoFile.Width, logoFile.Height));
            // MemoryStream tempStream = new MemoryStream();
            newBitmap.Save(imageFile, ImageFormat.Png);
        }
    }
    finally
    {
        if (g != null) g.Dispose();
        if (newBitmap != null) newBitmap.Dispose();
    }

}
/// <summary>
/// 绘制文本自动换行(超出截断)
/// </summary>
/// <param name=\"graphic\">绘图图面</param>
/// <param name=\"font\">字体</param>
/// <param name=\"text\">文本</param>
/// <param name=\"recangle\">绘制范围</param>
private void DrawStringWrap(Graphics graphic, Font font, string text, Rectangle recangle, int top = 0)
{
    List<string> textRows = GetStringRows(graphic, font, text, recangle.Width);
    int rowHeight = (int)(Math.Ceiling(graphic.MeasureString("测试", font).Height));
    int maxRowCount = recangle.Height / rowHeight;
    int drawRowCount = (maxRowCount < textRows.Count) ? maxRowCount : textRows.Count;
    //int top = (recangle.Height - rowHeight * drawRowCount) / 2;
    //int top = 0;
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Near;
    sf.LineAlignment = StringAlignment.Center;
    for (int i = 0; i < drawRowCount; i++)
    {
        Rectangle fontRectanle = new Rectangle(recangle.Left, top + rowHeight * i, recangle.Width, rowHeight);
        graphic.DrawString(textRows[i], font, new SolidBrush(Color.Black), fontRectanle, sf);
    }
}
/// <summary>
/// 绘制居中的标题(超出截断)
/// </summary>
/// <param name=\"graphic\">绘图图面</param>
/// <param name=\"font\">字体</param>
/// <param name=\"text\">文本</param>
/// <param name=\"recangle\">绘制范围</param>
private void DrawStringTitle(Graphics graphic, Font font, string text, Rectangle recangle, int top = 0)
{
    List<string> textRows = GetStringRows(graphic, font, text, recangle.Width);
    int rowHeight = (int)(Math.Ceiling(graphic.MeasureString("测试", font).Height));
    int maxRowCount = recangle.Height / rowHeight;
    int drawRowCount = (maxRowCount < textRows.Count) ? maxRowCount : textRows.Count;
    //int top = (recangle.Height - rowHeight * drawRowCount) / 2;
    //int top = 0;
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Center;
    sf.LineAlignment = StringAlignment.Center;

    for (int i = 0; i < drawRowCount; i++)
    {
        Rectangle fontRectanle = new Rectangle(recangle.Left, top + rowHeight * i, recangle.Width, rowHeight);
        graphic.DrawString(textRows[i], font, new SolidBrush(Color.Black), fontRectanle, sf);
    }
}
/// <summary>
/// 将文本分行
/// </summary>
/// <param name=\"graphic\">绘图图面</param>
/// <param name=\"font\">字体</param>
/// <param name=\"text\">文本</param>
/// <param name=\"width\">行宽</param>
/// <returns></returns>
private List<string> GetStringRows(Graphics graphic, Font font, string text, int width)
{
    int RowBeginIndex = 0;
    int rowEndIndex = 0;
    int textLength = text.Length;
    List<string> textRows = new List<string>();
    for (int index = 0; index < textLength; index++)
    {
        rowEndIndex = index;
        if (index == textLength - 1)
        {
            textRows.Add(text.Substring(RowBeginIndex));
        }
        else if (rowEndIndex + 1 < text.Length && text.Substring(rowEndIndex, 1) == "\n")
        {
            textRows.Add(text.Substring(RowBeginIndex, rowEndIndex - RowBeginIndex));
            rowEndIndex = index += 1;
            RowBeginIndex = rowEndIndex;
        }
        else if (graphic.MeasureString(text.Substring(RowBeginIndex, rowEndIndex - RowBeginIndex + 1), font).Width > width)
        {
            textRows.Add(text.Substring(RowBeginIndex, rowEndIndex - RowBeginIndex));
            RowBeginIndex = rowEndIndex;
        }
    }
    return textRows;
}

调用示例:

 ConvertTextFileToImage(".NET(C#)new关键字的三种用法", "new是我们大家所熟知的英文单词,但在C#中,它是一个关键字,它可以做运算符,也可以做修饰符,还可以用在泛型T参数约束中。下面我们来介绍一下这3种用法。", @"E:\softwaredir\\img\logo.png", @"E:\softwaredir\\img\th.png");


推荐文档