77 votes

Comment générer une image à partir d'un texte à la volée au moment de l'exécution ?

Quelqu'un peut-il me guider pour générer une image à partir d'un texte d'entrée ? L'image peut avoir n'importe quelle extension, cela n'a pas d'importance.

0 votes

Voulez-vous dire une image comme celle que l'on obtient à partir d'une capture d'écran ? Certainement, un peu de les formats/extensions seraient meilleurs que d'autres.

0 votes

Quel type de saisie de texte voulez-vous dire ?

0 votes

Non, ce n'est pas une capture d'écran, nous avons une zone de saisie de texte et nous utilisons C#.

189voto

Kazar Points 16014

En supposant que vous vouliez dessiner une chaîne sur une image en C#, vous allez devoir utiliser l'espace de noms System.Drawing :

private Image DrawText(String text, Font font, Color textColor, Color backColor)
{
    //first, create a dummy bitmap just to get a graphics object
    Image img = new Bitmap(1, 1);
    Graphics drawing = Graphics.FromImage(img);

    //measure the string to see how big the image needs to be
    SizeF textSize = drawing.MeasureString(text, font);

    //free up the dummy image and old graphics object
    img.Dispose();
    drawing.Dispose();

    //create a new image of the right size
    img = new Bitmap((int) textSize.Width, (int)textSize.Height);

    drawing = Graphics.FromImage(img);

    //paint the background
    drawing.Clear(backColor);

    //create a brush for the text
    Brush textBrush = new SolidBrush(textColor);

    drawing.DrawString(text, font, textBrush, 0, 0);

    drawing.Save();

    textBrush.Dispose();
    drawing.Dispose();

    return img;

}

Ce code mesurera d'abord la chaîne, puis créera une image de la taille correcte.

Si vous voulez sauvegarder le retour de cette fonction, il suffit d'appeler la méthode Save de l'image retournée.

10 votes

La ligne "Image img = new Bitmap(0, 0) ;", ne fonctionne pas : on ne peut pas créer une image de taille 0. Changez-la en "new Bitmap(1, 1)", cela fonctionne.

10 votes

Si vous ajoutez drawing.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; avant le drawing.DrawString(text, font, textBrush, 0, 0); vous obtiendrez un texte anti-alias plus lisse.

2 votes

Si vous doublez la taille de la police et que vous réduisez de moitié la taille de l'image résultante, vous obtiendrez des résultats encore meilleurs. Cette méthode est particulièrement efficace pour les petites polices et les symboles.

12voto

Merci Kazar. Une légère amélioration de la réponse précédente pour utiliser USING pour disposer des objets image/graphique après utilisation et l'introduction du paramètre de taille minimale.

    private Image DrawTextImage(String currencyCode, Font font, Color textColor, Color backColor) {
        return DrawTextImage(currencyCode, font, textColor, backColor, Size.Empty);
    }
    private Image DrawTextImage(String currencyCode, Font font, Color textColor, Color backColor, Size minSize) {
        //first, create a dummy bitmap just to get a graphics object
        SizeF textSize;
        using (Image img = new Bitmap(1, 1)) {
            using (Graphics drawing = Graphics.FromImage(img)) {
                //measure the string to see how big the image needs to be
                textSize = drawing.MeasureString(currencyCode, font);
                if (!minSize.IsEmpty) {
                    textSize.Width = textSize.Width > minSize.Width ? textSize.Width : minSize.Width;
                    textSize.Height = textSize.Height > minSize.Height ? textSize.Height : minSize.Height;
                }
            }
        }

        //create a new image of the right size
        Image retImg = new Bitmap((int)textSize.Width, (int)textSize.Height);
        using (var drawing = Graphics.FromImage(retImg)) {
            //paint the background
            drawing.Clear(backColor);

            //create a brush for the text
            using (Brush textBrush = new SolidBrush(textColor)) {
                drawing.DrawString(currencyCode, font, textBrush, 0, 0);
                drawing.Save();
            }
        }
        return retImg;
    }

6voto

Andrew Taylor Points 323

Voici la version de Panayiotis de la réponse de Kazar avec des paramètres optionnels et de la documentation, qui peut être ajoutée à une classe de bibliothèque.

/// <summary>
/// Creates an image containing the given text.
/// NOTE: the image should be disposed after use.
/// </summary>
/// <param name="text">Text to draw</param>
/// <param name="fontOptional">Font to use, defaults to Control.DefaultFont</param>
/// <param name="textColorOptional">Text color, defaults to Black</param>
/// <param name="backColorOptional">Background color, defaults to white</param>
/// <param name="minSizeOptional">Minimum image size, defaults the size required to display the text</param>
/// <returns>The image containing the text, which should be disposed after use</returns>
public static Image DrawText(string text, Font fontOptional=null, Color? textColorOptional=null, Color? backColorOptional=null, Size? minSizeOptional=null)
{
    Font font = Control.DefaultFont;
    if (fontOptional != null)
        font = fontOptional;

    Color textColor = Color.Black;
    if (textColorOptional != null)
        textColor = (Color)textColorOptional;

    Color backColor = Color.White;
    if (backColorOptional != null)
        backColor = (Color)backColorOptional;

    Size minSize = Size.Empty;
    if (minSizeOptional != null)
        minSize = (Size)minSizeOptional;

    //first, create a dummy bitmap just to get a graphics object
    SizeF textSize;
    using (Image img = new Bitmap(1, 1))
    {
        using (Graphics drawing = Graphics.FromImage(img))
        {
            //measure the string to see how big the image needs to be
            textSize = drawing.MeasureString(text, font);
            if (!minSize.IsEmpty)
            {
                textSize.Width = textSize.Width > minSize.Width ? textSize.Width : minSize.Width;
                textSize.Height = textSize.Height > minSize.Height ? textSize.Height : minSize.Height;
            }
        }
    }

    //create a new image of the right size
    Image retImg = new Bitmap((int)textSize.Width, (int)textSize.Height);
    using (var drawing = Graphics.FromImage(retImg))
    {
        //paint the background
        drawing.Clear(backColor);

        //create a brush for the text
        using (Brush textBrush = new SolidBrush(textColor))
        {
            drawing.DrawString(text, font, textBrush, 0, 0);
            drawing.Save();
        }
    }
    return retImg;
}

3voto

Toad Points 7868

Utiliser imagemagick pour le rendu du texte sur les images (sur le serveur)

Puisque vous êtes en C#, vous pouvez également utiliser les classes .Net pour la manipulation des bitmaps et des polices directement (avec des classes comme : System.Drawing.Bitmap y System.Drawing.Graphics )

3voto

Freddy Points 461

Je viens de traduire cette méthode mentionnée dans ce réponse à une méthode VB.NET. Peut-être que cela aidera quelqu'un.

Public Function DrawText(ByVal text As String, ByRef font As   Font, ByRef textColor As Color, ByRef backColor As Color) As Image
    ' first, create a dummy bitmap just to get a graphics object
    Dim img As Image = New Bitmap(1, 1)
    Dim drawing As Graphics = Graphics.FromImage(img)

    ' measure the string to see how big the image needs to be
    Dim textSize As SizeF = drawing.MeasureString(Text, Font)

    ' free up the dummy image and old graphics object
    img.Dispose()
    drawing.Dispose()

    ' create a new image of the right size
    img = New Bitmap(CType(textSize.Width, Integer), CType(textSize.Height, Integer))

    drawing = Graphics.FromImage(img)

    ' paint the background
    drawing.Clear(BackColor)

    ' create a brush for the text
    Dim textBrush As Brush = New SolidBrush(textColor)

    drawing.DrawString(text, font, textBrush, 0, 0)

    drawing.Save()

    textBrush.Dispose()
    drawing.Dispose()

    Return img

End Function

Editar : Correction de la faute de frappe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X