Renderização de texto usando a biblioteca de fontes | .NET

Visão geral

Se você alguma vez quis ter o recurso de renderizar um texto em uma imagem, o artigo aqui ensinará como fazê -lo com fontes de qualquer formato, suportado pela Biblioteca de fontes usando a solução API ASPOPE.FONT. A biblioteca permite converter o texto facilmente em imagens e adicionar texto a qualquer imagem.

Renderizando texto

Para inserir o texto em uma imagem, você precisará usar drawText Método da classe renderingutils. O código abaixo mostra como adicionar o texto “Hello World”, escrito na fonte Arial a uma imagem chamada “arial.png”.

 1    var dataDir = @"C:\Temp\";
 2    var fileName = dataDir + "arial.ttf"; //Font file name with full path
 3    var outFile = dataDir + "arial.png";
 4    var fontDefinition = new FontDefinition(FontType.TTF, new FontFileDefinition("ttf", new FileSystemStreamSource(fileName)));
 5    var ttfFont = Font.Open(fontDefinition) as 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);

O resultado da implementação:

Olá Arial

O método drawText permite definir o espaçamento da linha e executar o embrulho de texto de palavra por palavra automática.

No exemplo do código abaixo, especificamos o tipo de espaçamento de linha linespacingType.pixels e o definimos como 10, e definimos a largura máxima da imagem como 450.

Todo o texto que não pode ser exibido corretamente no intervalo especificado (no nosso caso é 450) será envolvido em uma nova linha.

O código cortado mostra como renderizar texto “Hello World” em fonte Arial com a embalagem da próxima linha:

 1    var dataDir = @"C:\Temp\";
 2    var fileName = dataDir + "arial.ttf"; //Font file name with full path
 3    var outFile = dataDir + "arial.png";
 4    var fontDefinition = new FontDefinition(FontType.TTF, new FontFileDefinition("ttf", new FileSystemStreamSource(fileName)));
 5    var ttfFont = Font.Open(fontDefinition) as 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);

O resultado da implementação:

Hello Arial Text Wrap

Neste exemplo, você viu como você pode transformar o texto em uma imagem com apenas uma linha de código.

A família de funções para o método drawText() abrange texto padrão ou saída de texto multilina. Mas, em alguns casos, você pode precisar de uma saída personalizada do texto, por exemplo, quando deseja comprimir, esticar, girar o texto em um ângulo ou outra coisa. Nesse caso, você precisa personalizar a saída de acordo com suas necessidades.

Renderização de texto personalizada

O próximo exemplo mostra uma maneira mais avançada (personalizada) de converter texto em uma imagem.

Para desenhar glifos dentro de Aspose.font, usa um dos métodos renderglyph() da classe glyphoutlineRenderer. Todos esses métodos sobrecarregados são declarados na interface iglyphRienderer.

Como parâmetro, devemos passar para esses métodos uma referência à fonte, glifídeo ou índice de glifos e as coordenadas de saída do glifo. Para transferir o último parâmetro, uma matriz especial representada pelo objeto Aspose.font transformationMatrix é usada. Abaixo, mostramos como usar objetos da transformationMatrix tipo para passar as coordenadas de saída do glifo para os métodos da família renderglyph().

Portanto, para desenhar um glifo, precisamos criar um objeto do tipo glyphoutlineRender. Mas esse objeto não pode desenhar um glifo por conta própria. Requer funcionalidade externa, descrita pela interface iglyphoutLinePainter. Para usar o objeto glyphoutlineRenderer, deve ser fornecido com uma implementação do iglyphoutLinePainter. Abaixo, você pode ver uma implementação simples desta interface. Vamos criar a classeglyphoutlinepainterque requer um objeto de System.drawing.drawing2d.graphicsPath Tipo para objetivos de desenho gráfico.

A implementação é ilustrada abaixo.

 1    Classe pública 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    }

Após a implementação iglyphoutLinePainter, podemos usar objetos de seu tipo para renderizar um glifo individual, passando -os para o glyphoutlineRenderer e chamando os métodos sobrecarregados correspondentes da família renderglyph().

Para renderizar uma sequência de texto, necessitamos de obter o glyphId para cada caractere e depois, utilizando um objeto do tipo GlyphOutlineRenderer, chamar um dos métodos da família RenderGlyph(), passando as coordenadas do glifo correspondente.

Vamos dar uma olhada em um exemplo de saída de uma linha de texto usando a biblioteca Aspose.font. Ele será construído na forma do método CustomDrawText(), que aceita parâmetros - *CustomDrawText *(texto da string, font ifent, fontsize duplo, escova de fundo, pincel textbrush, string outfile).

Crie o método CustomDrawText() que atrai o texto especificado no objeto System.Drawing.bitmap e salva o bitmap resultante no disco.

Isso incluirá as seguintes etapas:

Etapas auxiliares para esta estratégia

A implementação do método CustomDrawText() é mostrada abaixo.

 1    public static void CustomDrawText (texto da string, fonte ifont, Fontsize duplo, pincel BackgroundBrush, pincel TextBrush, String Outfile)
 2    {
 3        // Obtenha identificadores de glifos para cada símbolo na linha de texto
 4        Glifídeo [] gids = novo glifídeo [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    }

Método de utilidade para converter a largura da fonte em largura da imagem

1    estático duplo fontWidthToImagewith (largura dupla, int fontsourcerceresuluição, fontsize duplo, dpi duplo = 300)
2    {
3        Duplo ResolutionCorrection = DPI / 72; // 72 é o DPI interno da fonte
4
5        return (width / fontSourceResulution) * fontSize * resolutionCorrection;
6    }

O próximo snippet de código mostra como renderizar o texto “Hello World” usando o método CustomDrawText().

 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");

Implementando o código, obteremos o seguinte resultado:

O resultado da implementação:

Olá Arial Arial

Olá calibri Calibri

Kerning

Usando o valor da variável * Kerning *, você pode alterar a distância entre os glifos. Agora vamos reescrever o código na próxima maneira:

1 
2    // Posicionamento do glifo - Aumente o glifo x coordenada de acordo com a distância de kerning
3    kerning *= 1,25;
4    glyphxcoordinate += kerning;

O próximo resultado será obtido:

O resultado da implementação:

Olá Arial Kerning Arial kernint

Olá Calibri Kerning Calibri kerning

Renderizar texto por coordenadas

As variáveis ​​glyphxcoordinate e glifycoordinate são responsáveis ​​pelas coordenadas da saída de texto. Alterando o código da seguinte forma:

1    // declarar variáveis ​​de coordenadas e o GID anterior
2    Glifídeo anteriorgid = nulo;
3    dupla glifxcoordinada = 300;
4    glifycoordinada dupla = 300;

O próximo resultado será obtido:

O resultado da implementação:

Olá Arial Kerning Arial x=300 y=300

Olá Calibri Kerning Calibri x=300 y=300

Como adicionar o texto a uma imagem

Você também pode exibir o texto em uma imagem existente. Para isso, reescreveremos o código da seguinte forma:

 1 
 2    public static void CustomDrawText (texto da string, fonte ifont, Double FontSize, Bornchbrush Background, escova Textbrush, String Outfile, Bitmap Bitmap, Kerningcoefficiente duplo = 1, coordenado duplo = 0, coordenada dupla = 0)
 3    {
 4        // Obtenha identificadores de glifos para cada símbolo na linha de texto
 5        Glifídeo [] gids = novo glifídeo [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    }

Vamos modificar a maneira como o método é chamado:

 1    var dataDir = @"C:\Temp\";
 2    var fileName1 = dataDir + "arial.ttf"; //Font file name with full path
 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);

O resultado da implementação:

Hello Arial Shadow Effect Arial shadow effect

Emitindo o texto de cima para baixo

Para exibir o texto de cima para baixo, vamos fazer as seguintes alterações no método CustomDrawText().

 1    public static void CustomDrawText (texto da string, fonte ifont, fontsize duplo, pincel BackgroundBrush, pincel Textbrush, String Outfile, bitmap bitmap, duplo kerningcoeffect = 1, coordeninado duplo = 0, coordenada dupla = 0, bool towdown = false)
 2    {
 3        // Obtenha identificadores de glifos para cada símbolo na linha de texto
 4        Glifídeo [] gids = novo glifídeo [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    }

O código da chamada do método terá a próxima aparência:

1    var dataDir = @"C:\Temp\";
2    var fileName1 = dataDir + "arial.ttf"; //Font file name with full path
3    var fontDefinition1 = new FontDefinition(FontType.TTF, new FontFileDefinition("ttf", new FileSystemStreamSource(fileName1)));
4    var ttfFont1 = Font.Open(fontDefinition1) as TtfFont;
5    var bitmap = new Bitmap(960, 720);
6
7    GlyphOutlinePainter.CustomDrawText("Top down", ttfFont1, 18, Brushes.White, Brushes.Black, dataDir + "Hello_Arial_TopDown.png", bitmap, 1, 400, 00, true);

O resultado da implementação:

Olá Arial Top para Down Arial top to down

Informações adicionais

1    DPI duplo; // pontos por polegada
2    Duplo ResolutionCorrection = DPI / 72; // 72 é o DPI interno da fonte
3    // coordenam variáveis
4    glifxcoordinado duplo; // x
5    glifycoordinada dupla; // y;
6    // Kerning - espaçamento horizontal entre duas letras
7    duplo kerning = 0;

Have any questions about Aspose.Font?



Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.