Rendu de texte à l'aide de la bibliothèque de polices | .NET
Aperçu
Si vous avez toujours souhaité pouvoir restituer du texte dans une image, l’article ici vous apprendra comment le faire avec des polices de n’importe quel format, prises en charge par la bibliothèque de polices utilisant la solution API Aspose.Font. La bibliothèque vous permet de convertir facilement du texte en images et d’ajouter du texte à n’importe quelle image.
Rendu du texte
Pour insérer du texte dans une image, vous devrez utiliser la méthode DrawText de la classe RenderingUtils. Le code ci-dessous montre comment ajouter le texte « Bonjour tout le monde » écrit en police Arial à une image nommée « 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);
Le résultat de la mise en œuvre :
La méthode DrawText vous permet de définir l’espacement des lignes et d’effectuer un habillage automatique du texte mot par mot.
Dans l’exemple de code ci-dessous, nous avons spécifié le type d’espacement des lignes LineSpacingType.Pixels et l’avons défini sur 10, et nous avons défini la largeur maximale de l’image sur 450.
Tout le texte qui ne peut pas être affiché correctement dans la plage donnée (dans notre cas, il s’agit de 450) sera renvoyé sur une nouvelle ligne.
Le code extrait montre comment restituer le texte « Hello World » en police Arial avec retour à la ligne suivante :
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);
Le résultat de la mise en œuvre :
Dans cet exemple, vous avez vu comment transformer du texte en image avec une seule ligne de code.
La famille de fonctions pour la méthode DrawText()
couvre la sortie de texte standard ou de texte multiligne. Mais, dans certains cas, vous aurez peut-être besoin d’une sortie personnalisée du texte, par exemple lorsque vous souhaitez compresser, étirer, faire pivoter le texte selon un angle ou autre chose. Dans ce cas, vous devez personnaliser la sortie en fonction de vos besoins.
Rendu de texte personnalisé
L’exemple suivant montre une manière plus avancée (personnalisée) de convertir du texte en image.
Pour dessiner des
glyphs dans Aspose.Font, utilisez l’une des méthodes RenderGlyph()
de la classe
GlyphOutlineRenderer. Toutes ces méthodes surchargées sont déclarées dans l’interface
IGlyphRenderer.
En paramètre, nous devons passer à ces méthodes une référence à la police, au glyphId ou à l’index du glyphe, et aux coordonnées de sortie du glyphe. Pour transférer le dernier paramètre, une matrice spéciale représentée par l’objet Aspose.Font
TransformationMatrix est utilisée.
Ci-dessous, nous montrons comment utiliser des objets de type
TransformationMatrix pour transmettre les coordonnées de sortie des glyphes aux méthodes de la famille RenderGlyph()
.
Ainsi, pour dessiner un glyphe, nous devons créer un objet de type GlyphOutlineRenderer. Mais un tel objet ne peut pas dessiner à lui seul un glyphe. Il nécessite une fonctionnalité externe, qui est décrite par l’interface IGlyphOutlinePainter. Pour utiliser l’objet GlyphOutlineRenderer, il faut fournir une implémentation de IGlyphOutlinePainter.
Ci-dessous vous pouvez voir une implémentation simple de cette interface. Créons la classe GlyphOutlinePainter qui nécessite un objet de type System.Drawing.Drawing2D.GraphicsPath pour les objectifs de dessin graphique.
La mise en œuvre est illustrée ci-dessous.
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 }
Après l’implémentation de
IGlyphOutlinePainter, nous pouvons utiliser des objets de ce type pour restituer un glyphe individuel en les passant au
GlyphOutlineRenderer et en appelant les méthodes surchargées correspondantes de RenderGlyph()
famille.
Afin de restituer une chaîne de texte, nous devons obtenir le glyphId pour chaque caractère puis, à l’aide d’un objet de type
GlyphOutlineRenderer, appeler l’une des méthodes de la famille RenderGlyph()
, en passant les coordonnées du glyphe correspondant.
Jetons un coup d’œil à un exemple de sortie d’une ligne de texte à l’aide de la bibliothèque Aspose.Font. Il sera construit sous la forme de la méthode CustomDrawText()
, qui accepte les paramètres - CustomDrawText (texte de chaîne, police IFont, double fontSize, Brush backgroundBrush, Brush textBrush, string outFile).
Créez la méthode CustomDrawText()
qui dessine le texte spécifié dans l’objet
System.Drawing.Bitmap et enregistre le bitmap résultant sur le disque.
Cela comprendra les étapes suivantes :
- Itérer tous les symboles dans une chaîne de texte.
- Obtenez l’identifiant de glyphe pour chaque symbole traité - gid.
- Créez un objet de type GlyphOutlinePainter requis par le sous-système de rendu pour dessiner le glyphe actuel.
- Créez un objet de type Aspose.Font.Renderers.GlyphOutlineRenderer, et passez l’objet que vous venez de créer de type GlyphOutlinePainter dans le constructeur de GlyphOutlineRenderer. Cet objet GlyphOutlineRenderer est destiné à restituer les glyphes spécifiés.
- Rendre le glyphe actuellement traité à l’aide de la méthode GlyphOutlineRenderer.RenderGlyph(). L’objet Aspose.Fonts.Matrix est utilisé pour spécifier les coordonnées du glyphe. Le glyphe à restituer est spécifié par le paramètre gid.
Étapes auxiliaires pour cette stratégie
- Les coordonnées du glyphe pour l’axe « Y » sont constantes pour cet extrait de code.
- Les coordonnées du glyphe pour l’axe « X » sont calculées pour chaque glyphe traité.
- Les coordonnées ‘X’ et ‘Y’ sont transmises à l’objet Aspose.Fonts.Matrix utilisé par GlyphOutlineRenderer pour dessiner des glyphes.
- La distance entre les glyphes juste et précédemment traités est calculée à chaque étape d’itération. Cela affecte chaque coordonnée « X » de glyphe.
- L’objet de type GlyphOutlineRenderer dessine des glyphes à l’aide de GlyphOutlinePainter non pas directement dans Bitmap, mais dans l’objet GraphicsPath passé dans le constructeur pour GlyphOutlinePainter, donc nous utilisez l’objet de type System.Drawing.Graphics pour dessiner GraphicsPath dans Bitmap.
- La méthode FontWidthToImageWith() calcule la largeur du glyphe pour le système de coordonnées bitmap.
L’implémentation de la méthode CustomDrawText() est présentée ci-dessous.
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 }
Méthode utilitaire pour convertir la largeur de la police en largeur de l’image
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 }
L’extrait de code suivant montre comment restituer le texte « Bonjour tout le monde » à l’aide de la méthode 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");
En implémentant le code, nous obtiendrons le résultat suivant :
Le résultat de la mise en œuvre :
Arial
Calibre
Crénage
En utilisant la valeur de la variable crénage, vous pouvez modifier la distance entre les glyphes. Réécrivons maintenant le code de la manière suivante :
1
2 //Glyph positioning - increase glyph X coordinate according to the kerning distance
3 kerning *= 1.25;
4 glyphXCoordinate += kerning;
Le résultat suivant sera obtenu :
Le résultat de la mise en œuvre :
Arial kernint
Crénage Calibri
Rendu du texte par coordonnées
Les variables glyphXCoordonnée et glyphYCoordonnée sont responsables des coordonnées de la sortie du texte. En changeant le code comme suit :
1 //Declare coordinate variables and the previous gid
2 GlyphId previousGid = null;
3 double glyphXCoordinate = 300;
4 double glyphYCoordinate = 300;
Le résultat suivant sera obtenu :
Le résultat de la mise en œuvre :
Arial x=300 y=300
Calibre x=300 y=300
Comment ajouter le texte à une image
Vous pouvez également afficher du texte sur une image existante. Pour cela, nous allons réécrire le code comme suit :
1
2 public static void CustomDrawText(string text, IFont font, double fontSize, Brush backgroundBrush, Brush textBrush, string outFile, Bitmap bitmap, double kerningCoefficient = 1, double coordinateX = 0, double coordinateY = 0)
3 {
4 //Get glyph identifiers for every symbol in the text line
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 }
Modifions la façon dont la Méthode est appelée :
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);
Le résultat de la mise en œuvre :
Effet d’ombre aérienne
Sortie du texte de haut en bas
Pour afficher le texte de haut en bas, apportons les modifications suivantes dans la méthode CustomDrawText()
.
1 public static void CustomDrawText(string text, IFont font, double fontSize, Brush backgroundBrush, Brush textBrush, string outFile, Bitmap bitmap, double kerningCoefficient = 1, double coordinateX = 0, double coordinateY = 0, bool topDown = false)
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 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 }
Le code de l’appel de méthode aura l’apparence suivante :
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);
Le résultat de la mise en œuvre :
Arial de haut en bas
Informations Complémentaires
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;