-1

I use this to write text to a bitmap:

using (Graphics graphics = Graphics.FromImage(bitmap))
        {
            using (Font font = new Font("Arial", 72))
            {
                    graphics.DrawString(text, font, Brushes.Gold, location);
            }

            // Save & dispose
        }

I would like to get an outline added. How can I do this? I tried a solution from 9 years ago using GraphicsPath, but could not get it working.

Random
  • 19
  • 3
  • Can you show an example of the outline you're expecting? – Stefan Jul 05 '20 at 21:35
  • 1
    `DrawPath` will do the job - Example: `using (Bitmap bitmap = new Bitmap(100, 100)) using (Graphics graphics = Graphics.FromImage(bitmap)) using (Font font = new Font("Arial", 72)) using (StringFormat fmt = new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }) using (GraphicsPath gp = new GraphicsPath()) { gp.AddString("X", font.FontFamily, 1, 72, new Rectangle( Point.Empty, bitmap.Size), fmt); graphics.DrawPath(Pens.Black, gp); bitmap.Save(filename, ImageFormat.Png) }` – TaW Jul 05 '20 at 21:52
  • 2
    [Properly draw text using GraphicsPath](https://stackoverflow.com/a/53074638/7444103) – Jimi Jul 06 '20 at 03:20
  • @TaW for some reason I can only get one character from your code? I changed X into a string, but I only get the first letter of it. – Random Jul 06 '20 at 06:46
  • Is the bitmap large enough for the whole string? You can get the necessary minimum size from `gp.GetBounds();` You may want to re-order the `using` clauses for this.. – TaW Jul 06 '20 at 06:58

1 Answers1

1

From an old project of mine:

using(Bitmap bmp = new Bitmap(1000, 1000))
{
    Bitmap bmp2 = captionImage(bmp, new SolidColorBrush(Color.FromArgb(255, 255, 255, 255)), new SolidColorBrush(Color.FromArgb(255, 0, 0, 0)), "Hello World", "Arial", 24 , 4.0f, true, false, false, 10, 10);

    bmp2.Save("foo.png");
}

    public System.Drawing.Bitmap captionImage(System.Drawing.Bitmap img, System.Windows.Media.Brush fontColor, System.Windows.Media.Brush strokeColor, string text, string font, float fontSize, float strokeThickness, bool bold, bool italic, bool underline, int left, int top)
    {
        int style;

        float calculatedStrokeThickness;

        System.Drawing.Brush strokeBrush;

        System.Drawing.FontFamily c;


        style = 0;
        strokeBrush = BrushToDrawingBrush(strokeColor);
        calculatedStrokeThickness = fontSize * (strokeThickness * 0.1f);

        if (bold == true)
            style ^= (int)System.Drawing.FontStyle.Bold;

        if (italic == true)
            style ^= (int)System.Drawing.FontStyle.Italic;

        if (underline == true)
            style ^= (int)System.Drawing.FontStyle.Underline;

        c = MatchFontFamily(font);

        if (c == null)
            c = MatchFontFamily("Arial");

        if (c != null)
        {
            using (System.Drawing.StringFormat sf = new System.Drawing.StringFormat())
            {

                sf.Alignment = System.Drawing.StringAlignment.Near;
                sf.LineAlignment = System.Drawing.StringAlignment.Near;
                
                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(img))
                {
                    using (System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath())
                    {
                        try
                        {
                            path.AddString(text, c, style, fontSize, new System.Drawing.Point(left, top), sf);

                            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                            for (float i = 0; i < calculatedStrokeThickness; i += 5)
                            {
                                using (System.Drawing.Pen p = new System.Drawing.Pen(strokeBrush, i))
                                {
                                    p.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;
                        

                                    if (strokeThickness > 0.0f)
                                    {
                                        //g.FillPath(System.Drawing.Brushes.Red, path);
                                        g.DrawPath(p, path);
                                    }
                                }
                            }

                            g.FillPath(BrushToDrawingBrush(fontColor), path);
                        }
                        catch (Exception x)
                        {
                            x.ToString();
                        }
                    }
                }
            }
        }
        else
            MessageBox.Show("Unable to load fonts");

        return img;
    }

    private System.Drawing.Brush BrushToDrawingBrush(Brush brush)
    {
        Color color;

        System.Drawing.Brush ret;


        color = ((SolidColorBrush)brush).Color;
        ret = new System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B));

        return ret;
    }
John
  • 5,942
  • 3
  • 42
  • 79