使用字体库的文本渲染| .NET

概述

如果您想将文本渲染到图像中的功能,则此处的文章将教您如何使用任何格式的字体进行操作,并在字体库中使用Aspose.font API解决方案支持。该库允许您轻松地将文本转换为图像,并将文本添加到任何图像中。

渲染文字

要将文本插入图像中,您需要使用 drawText renderingutils类的方法。下面的代码显示了如何添加用Arial字体编写的文本“ Hello World”到名为“ Arial.png”的图像。

 1    var datadir = @“ c:\ temp \”;
 2    var filename = datadir + arial.ttf; //带有完整路径的字体文件名
 3    var outfile = datadir + arial.png;
 4    var fontdefinition = new fontdefinition(fonttype.ttfnew fontfiledefinition( ttf”,new filesystemstreamsource(filename)));
 5    var ttffont = font.open(fontDefinition)作为ttffont;
 6
 7    var stream = Aspose.Font.Renderers.RenderingUtils.DrawText(ttfFont, "Hello world", 18);
 8
 9    var bitmap = new Bitmap(stream);
10    bitmap.Save(outFile);

实现结果:

你好,阿里亚尔

drawText方法允许您设置线间距并执行自动逐字文本包装。

在下面的代码示例中,我们指定了线间距类型 lines -pacingtype.pixels并将其设置为10,然后将图像的最大宽度设置为450

在给定范围内无法正确显示的所有文本(在我们的情况下为450)将包裹在新线路上。

剪切的代码显示了如何在Arial字体中渲染“ Hello World”文本,并包裹到下一行:

 1    var datadir = @“ c:\ temp \”;
 2    var filename = datadir + arial.ttf; //带有完整路径的字体文件名
 3    var outfile = datadir + arial.png;
 4    var fontdefinition = new fontdefinition(fonttype.ttfnew fontfiledefinition( ttf”,new filesystemstreamsource(filename)));
 5    var ttffont = font.open(fontDefinition)作为ttffont;
 6    var linesPacingType = linesPacingType.pixels;
 7
 8    var stream = DrawText(ttfFont, "Hello world", 22, lineSpacingType, 10, 450);
 9
10    var bitmap = new Bitmap(stream);
11
12    bitmap.Save(outFile);

实现结果:

您好Arial文字包装

在此示例中,您看到了如何仅使用一行代码将文本变成图像。

drawText()方法的函数家族涵盖标准文本或多行文本输出。但是,在某些情况下,您可能需要文本的自定义输出,例如,当您想以角度或其他方式压缩,伸展,旋转文本时。在这种情况下,您需要根据需要自定义输出。

自定义文本渲染

下一个示例显示了一种更高级的(自定义)将文本转换为图像的方法。

在aspose.font中绘制 glyphs使用 glyphoutlinererer类的方法之一。所有这些超载方法均在 iglyphrenderer接口中声明。

我们必须将字体的引用、字形ID或字形索引以及字形输出坐标作为参数传递给这些方法。为了传输最后一个参数,我们使用了一个由 Aspose.Font TransformationMatrix 对象表示的特殊矩阵。 下面我们将展示如何使用 TransformationMatrix 类型的对象将字形输出坐标传递给 RenderGlyph() 系列方法。

因此,要绘制字形,我们需要创建一个 GlyphOutlineRenderer 类型的对象。但此类对象无法自行绘制字形。它需要外部功能,该功能由 IGlyphOutlinePainter 接口描述。要使用 GlyphOutlineRenderer 对象,需要提供 IGlyphOutlinePainter 接口的实现。

下面您可以看到此接口的一个简单实现。 让我们创建 GlyphOutlinePainter 类,它需要一个 System.Drawing.Drawing2D.GraphicsPath 类型的对象来实现图形绘制目标。

实现如下所示。

 1    public class GlyphOutlinePainter : IGlyphOutlinePainter
 2    {
 3        private GraphicsPath _path;
 4        private PointF _currentPoint;
 5
 6        public GlyphOutlinePainter(GraphicsPath path)
 7        {
 8            _path = path;
 9        }
10
11        public void MoveTo(MoveTo moveTo)
12        {
13            _path.CloseFigure();
14            _currentPoint.X = (float)moveTo.X;
15            _currentPoint.Y = (float)moveTo.Y;
16        }
17
18        public void LineTo(LineTo lineTo)
19        {
20            float x = (float)lineTo.X;
21            float y = (float)lineTo.Y;
22            _path.AddLine(_currentPoint.X, _currentPoint.Y, x, y);
23            _currentPoint.X = x;
24            _currentPoint.Y = y;
25        }
26
27        public void CurveTo(CurveTo curveTo)
28        {
29            float x3 = (float)curveTo.X3;
30            float y3 = (float)curveTo.Y3;
31
32            _path.AddBezier(
33                _currentPoint.X,
34                _currentPoint.Y,
35                (float)curveTo.X1,
36                (float)curveTo.Y1,
37                (float)curveTo.X2,
38                (float)curveTo.Y2,
39                x3,
40                y3);
41
42            _currentPoint.X = x3;
43            _currentPoint.Y = y3;
44        }
45
46        public void ClosePath()
47        {
48            _path.CloseFigure();
49        }
50    }

IGlyphOutlinePainter 实现之后,我们可以使用其类型的对象来渲染单个字形,方法是将它们传递给 GlyphOutlineRenderer 并调用 RenderGlyph() 系列的相应重载方法。

为了渲染一串文本,我们需要获取每个字符的 glyphId,然后使用 GlyphOutlineRenderer 类型的对象调用 RenderGlyph() 系列中的某个方法,并传递相应字形的坐标。

让我们来看一个使用 Aspose.Font 库输出一行文本的示例。它将以 CustomDrawText() 方法的形式构建,该方法接受以下参数:CustomDrawText(string text, IFont font, double fontSize, Brush backgroundBrush, Brush textBrush, string outFile)。

创建customDrawText()方法,该方法将指定的文本绘制到 system.drawing.bitmap对象中,并保存在光盘上的结果位图。

这将包括以下步骤:

950 / 5,000

此策略的辅助步骤

 1    public static void CustomDrawText(string text, IFont font, double fontSize, Brush backgroundBrush, Brush textBrush, string outFile)
 2    {
 3        //Get glyph identifiers for every symbol in the text line
 4        GlyphId[] gids = new GlyphId[text.Length];
 5
 6        for (int i = 0; i < text.Length; i++)
 7            gids[i] = font.Encoding.DecodeToGid(text[i]);
 8
 9        // Set common drawing settings
10        double dpi = 300;
11        double resolutionCorrection = dpi / 72; // 72 is font's internal dpi
12
13        // Prepare output bitmap                
14        Bitmap outBitmap = new Bitmap(960, 720);
15
16
17        outBitmap.SetResolution((float)dpi, (float)dpi);
18
19        Graphics outGraphics = Graphics.FromImage(outBitmap);
20        outGraphics.FillRectangle(backgroundBrush, 0, 0, outBitmap.Width, outBitmap.Height);
21        outGraphics.SmoothingMode = SmoothingMode.HighQuality;
22
23        //Declare coordinate variables and a previous gid
24        GlyphId previousGid = null;
25        double glyphXCoordinate = 0;
26        double glyphYCoordinate = fontSize * resolutionCorrection;
27
28        // The loop paints every glyph in gids
29        foreach (GlyphId gid in gids)
30        {
31            // if the font contains the gid
32            if (gid != null)
33            {
34                Glyph glyph = font.GlyphAccessor.GetGlyphById(gid);
35                if (glyph == null)
36                    continue;
37
38                // The path that accepts drawing instructions
39                GraphicsPath path = new GraphicsPath();
40
41                // Create IGlyphOutlinePainter implementation
42                GlyphOutlinePainter outlinePainter = new GlyphOutlinePainter(path);
43
44                // Create the renderer
45                Aspose.Font.Renderers.IGlyphRenderer renderer = new Aspose.Font.Renderers.GlyphOutlineRenderer(outlinePainter);
46
47                // Get common glyph properties
48                double kerning = 0;
49
50                // Get kerning value
51
52                if (previousGid != null)
53                {
54                    kerning = (font.Metrics.GetKerningValue(previousGid, gid) / glyph.SourceResolution) * fontSize * resolutionCorrection;
55                    kerning += FontWidthToImageWith(font.Metrics.GetGlyphWidth(previousGid), glyph.SourceResolution, fontSize);
56                }
57
58                // Glyph positioning - increase glyph X coordinate according to kerning distance
59                glyphXCoordinate += kerning;
60
61                // Glyph placement matrix
62                TransformationMatrix glyphMatrix = new TransformationMatrix(
63                        new double[]
64                                { fontSize * resolutionCorrection,
65                            0,
66                            0,
67                        // negative because of the bitmap coordinate system begins from the top
68                            - fontSize*resolutionCorrection,
69                            glyphXCoordinate,
70                            glyphYCoordinate
71                                });
72
73                // Render the current glyph
74                renderer.RenderGlyph(font, gid, glyphMatrix);
75
76                // Fill the path
77                path.FillMode = FillMode.Winding;
78
79                outGraphics.FillPath(textBrush, path);
80            }
81
82            //Set current gid as previous to get correct kerning for next glyph
83            previousGid = gid;
84        }
85
86        //Save the results
87        outBitmap.Save(outFile);
88    }

将字体宽度转换为图像宽度的实用方法

1    static double FontWidthToImageWith(double width, int fontSourceResulution, double fontSize, double dpi = 300)
2    {
3        double resolutionCorrection = dpi / 72; // 72 is font's internal dpi
4
5        return (width / fontSourceResulution) * fontSize * resolutionCorrection;
6    }

下一个代码段显示了如何使用customDrawText()`方法来渲染文本“ Hello World”。

 1    var dataDir = @"C:\Temp\";
 2    var fileName1 = dataDir + "arial.ttf"; //Font file name with full path
 3    var fileName2 = dataDir + "calibrii.ttf"; //Font file name with full path
 4
 5    var fontDefinition1 = new FontDefinition(FontType.TTF, new FontFileDefinition("ttf", new FileSystemStreamSource(fileName1)));
 6    var ttfFont1 = Font.Open(fontDefinition1) as TtfFont;
 7
 8    var fontDefinition2 = new FontDefinition(FontType.TTF, new FontFileDefinition("ttf", new FileSystemStreamSource(fileName2)));
 9    var ttfFont2 = Font.Open(fontDefinition2) as TtfFont;
10
11    GlyphOutlinePainter.CustomDrawText("Hello world", ttfFont1, 24, Brushes.White, Brushes.Black, dataDir + "Hello_Arial_out.png");
12    GlyphOutlinePainter.CustomDrawText("Hello world", ttfFont2, 24, Brushes.Yellow, Brushes.Blue, dataDir + "Hello_Calibri_out.png");

实施代码,我们将获得以下结果:

实现结果:

你好,阿里亚尔 Arial

你好钙纤维 Calibri

凯宁

使用 kerning变量的值,您可以更改字形之间的距离。现在,让我们下一步重写代码:

1 
2    //Glyph positioning - increase glyph X coordinate according to the kerning distance
3    kerning *= 1.25;
4    glyphXCoordinate += kerning;

下一个结果将得到:

实现结果:

您好Arial Kerning Arial kerning

你好Calibri Kerning Calibri kerning

通过坐标渲染文本

变量 * glyphxCoorcorion *和 * glyphyCoorcoriation *负责文本输出的坐标。通过更改代码如下:

1    //Declare coordinate variables and the previous gid
2    GlyphId previousGid = null;
3    double glyphXCoordinate = 300;
4    double glyphYCoordinate = 300;

下一个结果将得到:

实现结果:

您好Arial Kerning Arial x=300 y=300

你好Calibri Kerning Calibri x=300 y=300

如何将文本添加到图像

您还可以在现有图像上显示文本。为此,我们将按照以下方式重写:

 1 
 2    public static void customDrawText(字符串文本,Ifont FontDouble FontsizeBrush BackgroundbrushBrush TextbrushString Outfilebitmap bitmapdouble kerningCoofficity = 1double CoortionX = 0double coortiaty = 0)
 3    {
 4        //为文本行中的每个符号获取标识符
 5        glyphid [] gids = new Glyphid [text.length];
 6
 7        for (int i = 0; i < text.Length; i++)
 8            gids[i] = font.Encoding.DecodeToGid(text[i]);
 9
10        // Set common drawing settings
11        double dpi = 300;
12        double resolutionCorrection = dpi / 72; // 72 is font's internal dpi
13
14        // Prepare the output bitmap                
15        Bitmap outBitmap = bitmap;
16
17        outBitmap.SetResolution((float)dpi, (float)dpi);
18
19        Graphics outGraphics = Graphics.FromImage(outBitmap);
20        outGraphics.FillRectangle(backgroundBrush, 0, 0, outBitmap.Width, outBitmap.Height);
21        outGraphics.SmoothingMode = SmoothingMode.HighQuality;
22
23        //Declare coordinate variables and the previous gid
24        GlyphId previousGid = null;
25        double glyphXCoordinate = coordinateX;
26        double glyphYCoordinate = coordinateY;
27
28        glyphYCoordinate += fontSize * resolutionCorrection;
29
30        //The loop paints every glyph in gids
31        foreach (GlyphId gid in gids)
32        {
33            // if the font contains the gid
34            if (gid != null)
35            {
36                Glyph glyph = font.GlyphAccessor.GetGlyphById(gid);
37                if (glyph == null)
38                    continue;
39
40                // The path that accepts drawing instructions
41                GraphicsPath path = new GraphicsPath();
42
43                // Create the IGlyphOutlinePainter implementation
44                GlyphOutlinePainter outlinePainter = new GlyphOutlinePainter(path);
45
46                // Create the renderer
47                Aspose.Font.Renderers.IGlyphRenderer renderer = new Aspose.Font.Renderers.GlyphOutlineRenderer(outlinePainter);
48
49                // Get common glyph properties
50                double kerning = 0;
51
52                // Get the kerning value
53
54                if (previousGid != null)
55                {
56                    kerning = (font.Metrics.GetKerningValue(previousGid, gid) / glyph.SourceResolution) * fontSize * resolutionCorrection;
57                    kerning += FontWidthToImageWith(font.Metrics.GetGlyphWidth(previousGid), glyph.SourceResolution, fontSize);
58                }
59
60                // Glyph positioning - increase the glyph X coordinate according to the kerning distance
61                glyphXCoordinate += kerning * kerningCoefficient;
62
63                // Glyph placement matrix
64                TransformationMatrix glyphMatrix = new TransformationMatrix(
65                        new double[]
66                                { fontSize * resolutionCorrection,
67                            0,
68                            0,
69                        // negative because of the bitmap coordinate system begins from the top
70                            - fontSize*resolutionCorrection,
71                            glyphXCoordinate,
72                            glyphYCoordinate
73                                });
74
75                // Render the current glyph
76                renderer.RenderGlyph(font, gid, glyphMatrix);
77
78                // Fill the path
79                path.FillMode = FillMode.Winding;
80
81                outGraphics.FillPath(textBrush, path);
82            }
83
84            //Set the current gid as previous to get the correct kerning for the next glyph
85            previousGid = gid;
86        }
87
88        //Save the results
89        outBitmap.Save(outFile);
90    }

让我们修改该方法的调用方式:

 1    var dataDir = @"C:\Temp\";
 2    var filename1 = datadir + arial.ttf; //带有完整路径的字体文件名
 3
 4    var fontDefinition1 = new FontDefinition(FontType.TTF, new FontFileDefinition("ttf", new FileSystemStreamSource(fileName1)));
 5    var ttfFont1 = Font.Open(fontDefinition1) as TtfFont;
 6
 7    var bitmap = new Bitmap(960, 720);
 8
 9    GlyphOutlinePainter.CustomDrawText("Hello world", ttfFont1, 17, Brushes.White, Brushes.Black, dataDir + "Hello_Arial_out.png", bitmap);
10
11    var inputImagePath = dataDir + "Hello_Arial_out.png";
12    var bitmapAddText = new Bitmap(inputImagePath);
13
14    GlyphOutlinePainter.CustomDrawText("Hello world", ttfFont1, 17, Brushes.Transparent, Brushes.Gray, dataDir + "Hello_Arial_Shadow_out.png", bitmapAddText, 1, -3);
15
16    GlyphOutlinePainter.CustomDrawText("<= Shadow effect", ttfFont1, 17, Brushes.Transparent, Brushes.Brown, dataDir + "Hello_Arial_Shadow_out.png", bitmapAddText, 1, 400);

实现结果:

你好arial阴影效果 Arial shadow effect

从上到下输出文本

要显示从上到下的文本,让我们在customDrawText()方法中进行以下更改。

 1    public static void customDrawText(字符串文本,Ifont FontDouble FontsizeBrush BackgredbrushBrush TextbrushString Outfilebitmap bitmapdouble kerningCoofficity = 1double CoortionX = 0double Coordicy = 0double Coordicy = 0bool topdown = false = false)
 2    {
 3        //为文本行中的每个符号获取标识符
 4        glyphid [] gids = new Glyphid [text.length];
 5
 6        for (int i = 0; i < text.Length; i++)
 7            gids[i] = font.Encoding.DecodeToGid(text[i]);
 8
 9        // Set common drawing settings
10        double dpi = 300;
11        double resolutionCorrection = dpi / 72; // 72 is font's internal dpi
12
13        // Prepare the output bitmap                
14        Bitmap outBitmap = bitmap;
15
16        outBitmap.SetResolution((float)dpi, (float)dpi);
17
18        Graphics outGraphics = Graphics.FromImage(outBitmap);
19        outGraphics.FillRectangle(backgroundBrush, 0, 0, outBitmap.Width, outBitmap.Height);
20        outGraphics.SmoothingMode = SmoothingMode.HighQuality;
21
22        //Declare coordinate variables and the previous gid
23        GlyphId previousGid = null;
24        double glyphXCoordinate = coordinateX;
25        double glyphYCoordinate = coordinateY;
26
27        glyphYCoordinate += fontSize * resolutionCorrection;
28
29        //The loop paints every glyph in gids
30        foreach (GlyphId gid in gids)
31        {
32            // if the font contains the gid
33            if (gid != null)
34            {
35                Glyph glyph = font.GlyphAccessor.GetGlyphById(gid);
36                if (glyph == null)
37                    continue;
38
39                // The path that accepts drawing instructions
40                GraphicsPath path = new GraphicsPath();
41
42                // Create IGlyphOutlinePainter implementation
43                GlyphOutlinePainter outlinePainter = new GlyphOutlinePainter(path);
44
45                // Create the renderer
46                Aspose.Font.Renderers.IGlyphRenderer renderer = new Aspose.Font.Renderers.GlyphOutlineRenderer(outlinePainter);
47
48                // Get common glyph properties
49                double kerning = 0;
50
51                // Get kerning value                        
52                if (previousGid != null && !topDown)
53                {
54                    kerning = (font.Metrics.GetKerningValue(previousGid, gid) / glyph.SourceResolution) * fontSize * resolutionCorrection;
55                    kerning += FontWidthToImageWith(font.Metrics.GetGlyphWidth(previousGid), glyph.SourceResolution, fontSize);
56                }
57
58                if (topDown)
59                {
60                    glyphYCoordinate += fontSize * resolutionCorrection;
61                }
62                else
63                {
64                    // Glyph positioning - increase the glyph X coordinate according to kerning distance                       
65                    glyphXCoordinate += kerning * kerningCoefficient;
66                }
67
68                // Glyph placement matrix
69                TransformationMatrix glyphMatrix = new TransformationMatrix(
70                        new double[]
71                                { fontSize * resolutionCorrection,
72                            0,
73                            0,
74                        // negative because the bitmap coordinate system begins from the top
75                            - fontSize*resolutionCorrection,
76                            glyphXCoordinate,
77                            glyphYCoordinate
78                                });
79
80                // Render the current glyph
81                renderer.RenderGlyph(font, gid, glyphMatrix);
82
83                // Fill the path
84                path.FillMode = FillMode.Winding;
85
86                outGraphics.FillPath(textBrush, path);
87            }
88
89            //Set the current gid as previous to get correct kerning for the next glyph
90            previousGid = gid;
91        }
92
93        //Save the results
94        outBitmap.Save(outFile);
95    }

方法调用代码将有下一个外观:

1    var dataDir = @"C:\Temp\";
2    var filename1 = datadir + arial.ttf; //带有完整路径的字体文件名
3    var fontdefinition1 = new fontdefinition(fonttype.ttfnew fontfiledefinition( ttf”,new filesystemstreamsource(filename1)));
4    var ttffont1 = font.open(fontdefinition1)ttffont;
5    var bitmap =新的位图(960720);
6
7    GlyphOutlinePainter.CustomDrawText("Top down", ttfFont1, 18, Brushes.White, Brushes.Black, dataDir + "Hello_Arial_TopDown.png", bitmap, 1, 400, 00, true);

实现结果:

你好,上衣到下来 Arial top to down

附加信息

1    double dpi; // dots per inch
2    double resolutionCorrection = dpi / 72; // 72 is font's internal dpi
3    // Coordinate variables
4    double glyphXCoordinate; // X
5    double glyphYCoordinate; // Y;
6    // Kerning - horizontal spacing between two letters
7    double kerning = 0;

Have any questions about Aspose.Font?



Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.