如何将弯曲文本渲染为位图?

How can I render curved text into a Bitmap?(如何将弯曲文本渲染为位图?)
本文介绍了如何将弯曲文本渲染为位图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在动态创建位图并使用位图中的图形对象在其上绘制一个字符串,如下所示:

I am currently dynamically creating a bitmap and using the graphics object from the bitmap to draw a string on it like so:

System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.DrawString(text, font, brush, new System.Drawing.Point(0, 0));

这将返回一个矩形位图,其中的字符串从左到右直接写入.我也希望能够画出彩虹形状的绳子.我怎样才能做到这一点?

This returns a rectangular bitmap with the string written straight across from left to right. I would like to also be able to draw the string in the shape of a rainbow. How can I do this?

推荐答案

我最近遇到了这个问题(我正在渲染文本以​​打印到 CD 上),所以这是我的解决方案:

I recently had this problem (I was rendering text for printing onto CDs), so here's my solution:

private void DrawCurvedText(Graphics graphics, string text, Point centre, float distanceFromCentreToBaseOfText, float radiansToTextCentre, Font font, Brush brush)
{
    // Circumference for use later
    var circleCircumference = (float)(Math.PI * 2 * distanceFromCentreToBaseOfText);

    // Get the width of each character
    var characterWidths = GetCharacterWidths(graphics, text, font).ToArray();

    // The overall height of the string
    var characterHeight = graphics.MeasureString(text, font).Height;

    var textLength = characterWidths.Sum();

    // The string length above is the arc length we'll use for rendering the string. Work out the starting angle required to 
    // centre the text across the radiansToTextCentre.
    float fractionOfCircumference = textLength / circleCircumference;

    float currentCharacterRadians = radiansToTextCentre + (float)(Math.PI * fractionOfCircumference);

    for (int characterIndex = 0; characterIndex < text.Length; characterIndex++)
    {
        char @char = text[characterIndex];

        // Polar to cartesian
        float x = (float)(distanceFromCentreToBaseOfText * Math.Sin(currentCharacterRadians));
        float y = -(float)(distanceFromCentreToBaseOfText * Math.Cos(currentCharacterRadians));

        using (GraphicsPath characterPath = new GraphicsPath())
        {
            characterPath.AddString(@char.ToString(), font.FontFamily, (int)font.Style, font.Size, Point.Empty,
                                    StringFormat.GenericTypographic);

            var pathBounds = characterPath.GetBounds();

            // Transformation matrix to move the character to the correct location. 
            // Note that all actions on the Matrix class are prepended, so we apply them in reverse.
            var transform = new Matrix();

            // Translate to the final position
            transform.Translate(centre.X + x, centre.Y + y);

            // Rotate the character
            var rotationAngleDegrees = currentCharacterRadians * 180F / (float)Math.PI - 180F;
            transform.Rotate(rotationAngleDegrees);

            // Translate the character so the centre of its base is over the origin
            transform.Translate(-pathBounds.Width / 2F, -characterHeight);

            characterPath.Transform(transform);

            // Draw the character
            graphics.FillPath(brush, characterPath);
        }

        if (characterIndex != text.Length - 1)
        {
            // Move "currentCharacterRadians" on to the next character
            var distanceToNextChar = (characterWidths[characterIndex] + characterWidths[characterIndex + 1]) / 2F;
            float charFractionOfCircumference = distanceToNextChar / circleCircumference;
            currentCharacterRadians -= charFractionOfCircumference * (float)(2F * Math.PI);
        }
    }
}

private IEnumerable<float> GetCharacterWidths(Graphics graphics, string text, Font font)
{
    // The length of a space. Necessary because a space measured using StringFormat.GenericTypographic has no width.
    // We can't use StringFormat.GenericDefault for the characters themselves, as it adds unwanted spacing.
    var spaceLength = graphics.MeasureString(" ", font, Point.Empty, StringFormat.GenericDefault).Width;

    return text.Select(c => c == ' ' ? spaceLength : graphics.MeasureString(c.ToString(), font, Point.Empty, StringFormat.GenericTypographic).Width);
}

这篇关于如何将弯曲文本渲染为位图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)