6

I have been searching and looking for Drawing text with outline onto images?

Here my code

    private static void tulisnamafile(string imagepath, string textnya)
    {

        Image image = Image.FromStream(new MemoryStream(File.ReadAllBytes(imagepath)));
        Bitmap newImage = new Bitmap(640, 380);
        using (Graphics g = Graphics.FromImage(newImage))
        {
            // Draw base image
            g.DrawImageUnscaled(image, 0, 0);
            //Static is HERE
            SolidBrush brushing = new SolidBrush(Color.White);
            Font font = new Font(("Comic Sans MS"), 20.0f);
            int napoint = newImage.Height - 90;
            int napointa = image.Width - 200;
            FontFamily ff = new FontFamily("Times New Roman");
            int fontSize = 24;
            Font f = new Font(ff, fontSize, FontStyle.Regular);
            StringFormat sf = new StringFormat();
            Rectangle displayRectangle = new Rectangle(new Point(5, napoint), new Size(newImage.Width - 1, newImage.Height - 1));
            g.DrawEllipse(Pens.Magenta, new Rectangle(0, 0, 1, 1));
            GraphicsPath gp = new GraphicsPath();
            gp.AddString(textnya, ff, (int)FontStyle.Bold, fontSize + 4, new Point(0, 0), sf);
            g.FillPath(Brushes.White, gp);
            g.DrawPath(Pens.Black, gp);

            g.Flush(FlushIntention.Sync);
            g.Dispose();
        }
        image.Dispose();
        string fileName = "ab.jpg";
        string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
        MessageBox.Show(path);
        newImage.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);
        newImage.Dispose();
    }

and Its the trigger

    private void button3_Click(object sender, EventArgs e)
    {

        string imagename = "C:\\Documents and Settings\\admin\\My Documents\\Visual Studio 2008\\Projects\\template\\template\\bin\\Debug\\bg.jpg";
        tulisnamafile(imagename, "SlimPort® SP1002; Connect mobile devices to any big screen. High Speed micro USB");

    }

Check the Code result:

Messing resultnya Such messing result, UNWRAPPED and with white color

This what I want, and with wrapping?

This One

I found in CodeProject but not luck, its using C++. Based someone in neowin and tried this one too..

But still not luck.

UPDATE:

Here my working code, for who maybe need it... based from Abdias Software's code ( check the answers ), I make small changes ( there some error in those code).

        private static void tulisnamafile(string imagepath, string textnya)
    {

        float fontSize = 22;

        Image image = Image.FromStream(new MemoryStream(File.ReadAllBytes(imagepath)));
        //some test image for this demo
        Bitmap bmp = (Bitmap)Image.FromFile(imagepath);
        Graphics g = Graphics.FromImage(bmp);

        //this will center align our text at the bottom of the image
        StringFormat sf = new StringFormat();
        sf.Alignment = StringAlignment.Center;
        sf.LineAlignment = StringAlignment.Far;

        //define a font to use.
        Font f = new Font("Impact", fontSize, FontStyle.Bold, GraphicsUnit.Pixel);

        //pen for outline - set width parameter
        Pen p = new Pen(ColorTranslator.FromHtml("#77090C"), 8);
        p.LineJoin = LineJoin.Round; //prevent "spikes" at the path

        //this makes the gradient repeat for each text line
        Rectangle fr = new Rectangle(0, bmp.Height - f.Height, bmp.Width, f.Height);
        LinearGradientBrush b = new LinearGradientBrush(fr,
                                                        ColorTranslator.FromHtml("#FF6493"),
                                                        ColorTranslator.FromHtml("#D00F14"),
                                                        90);

        //this will be the rectangle used to draw and auto-wrap the text.
        //basically = image size
        Rectangle r = new Rectangle(0, 0, bmp.Width, bmp.Height);

        GraphicsPath gp = new GraphicsPath();

        //look mom! no pre-wrapping!
        gp.AddString(textnya, f.FontFamily, (int)FontStyle.Bold, fontSize, r, sf);

        //these affect lines such as those in paths. Textrenderhint doesn't affect
        //text in a path as it is converted to ..well, a path.    
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.PixelOffsetMode = PixelOffsetMode.HighQuality;

        //TODO: shadow -> g.translate, fillpath once, remove translate
        g.DrawPath(p, gp);
        g.FillPath(b, gp);

        //cleanup
        gp.Dispose();
        b.Dispose();
        b.Dispose();
        f.Dispose();
        sf.Dispose();
        g.Dispose();
        string fileName = "ab.jpg";
        string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
        bmp.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);
        bmp.Dispose();
    }
radiaku
  • 212
  • 2
  • 6
  • 18
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Dec 29 '12 at 00:42
  • @JohnSaunders thanks man... – radiaku Dec 29 '12 at 07:30

2 Answers2

27

Just to sum up:

Define a GraphicPath and then use DrawPath to draw outlined version of text, FillPath to draw a filled version.

For the second image with the woman, a second (filled) version is drawn first at a small offset.

For the gradient use LinearGradientBrush for brush. Thickness of the outline is defined by the Pen's thickness.

For wrapping define a StringFormat and use a Rectangle to define the region you want the text to be in.

To center the text you can define the rectangle to have the same width as the image, then set strformat.Alignment to Center.

UPDATE: To replicate the text in the second image you can use this code:

float fontSize = 52;

//some test image for this demo
Bitmap bmp = (Bitmap)Image.FromFile(s"test.jpg");
Graphics g = Graphics.FromImage(bmp);

//this will center align our text at the bottom of the image
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Far;

//define a font to use.
Font f = new Font("Impact", fontSize, FontStyle.Bold, GraphicsUnit.Pixel);

//pen for outline - set width parameter
Pen p = new Pen(ColorTranslator.FromHtml("#77090C"), 8);
p.LineJoin = LineJoin.Round; //prevent "spikes" at the path

//this makes the gradient repeat for each text line
Rectangle fr = new Rectangle(0, bmp.Height - f.Height, bmp.Width, f.Height);
LinearGradientBrush b = new LinearGradientBrush(fr,  
                                                ColorTranslator.FromHtml("#FF6493"),
                                                ColorTranslator.FromHtml("#D00F14"),
                                                90);

//this will be the rectangle used to draw and auto-wrap the text.
//basically = image size
Rectangle r = new Rectangle(0, 0, bmp.Width, bmp.Height);

GraphicsPath gp = new GraphicsPath();

//look mom! no pre-wrapping!
gp.AddString("Demo for Stack Overflow", 
             f.FontFamily, (int)f.Style, fontSize, r, sf);

//these affect lines such as those in paths. Textrenderhint doesn't affect
//text in a path as it is converted to ..well, a path.    
g.SmoothingMode = SmoothingMode.AntiAlias;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;

//TODO: shadow -> g.translate, fillpath once, remove translate
g.DrawPath(p, gp);
g.FillPath(b, gp);

//cleanup
gp.Dispose();
b.Dispose();
b.Dispose();
f.Dispose();
sf.Dispose();
g.Dispose();

bmp.Save(s"test_result.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Dispose();

This will produce this result:

Resulting image

To produce the extra "shadow" just translate the gfirst, draw filled, then remove the translation.

The FromHtml is used here as I picked the colors from your image and was to lazy to convert. Just use Color.FromARGB() or a fixed color - as you want.

VB version:

    Dim fontSize As Single = 52

    Dim bmp As Bitmap = Bitmap.FromFile("c:\test.jpg")
    Dim g As Graphics = Graphics.FromImage(bmp)

    Dim sf As New StringFormat(StringFormatFlags.NoClip)
    sf.Alignment = StringAlignment.Center
    sf.LineAlignment = StringAlignment.Far

    Dim f As New Font("Impact", fontSize, FontStyle.Bold, GraphicsUnit.Pixel)

    Dim p As New Pen(ColorTranslator.FromHtml("#77090C"), 4)
    p.LineJoin = LineJoin.Round

    'rectangle for font to repeat gradient for each line
    Dim fr As New Rectangle(0, bmp.Height - f.Height, bmp.Width, f.Height)
    Dim b As New LinearGradientBrush(fr,
                                     ColorTranslator.FromHtml("#FF6493"),
                                     ColorTranslator.FromHtml("#D00F14"),
                                     90)

    Dim r As New Rectangle(0, 0, bmp.Width, bmp.Height)
    Dim gp As New GraphicsPath

    gp.AddString("Demo for Stack Overflow",
                 f.FontFamily,
                 f.Style,
                 fontSize,
                 r,
                 sf)

    g.SmoothingMode = SmoothingMode.AntiAlias
    g.PixelOffsetMode = PixelOffsetMode.HighQuality

    g.DrawPath(p, gp)
    g.FillPath(b, gp)

    gp.Dispose() 'path
    b.Dispose() 'b
    b.Dispose()  'p
    f.Dispose()  'font
    sf.Dispose()  'stringformat
    g.Dispose()  'g

    bmp.Save("c:\test_result.jpg", Imaging.ImageFormat.Jpeg)
    bmp.Dispose()
  • there some error in your code, check my updated version... , I dont know why, but in visual studio C# 2008 express... getting some error. Anyways thanks again... :) – radiaku Dec 29 '12 at 10:14
  • I wrote it in VB originally for this post - something got broken during the translation to C# I guess. I'll check, thanks :) –  Dec 29 '12 at 20:13
3

A simple way to get "better" results could be to draw the text twice. Draw the shadow first, for example some pixels to the right and to the bottom, if you want the classic drop-shadow look, in gray color. You may also want to consider using a different font, any font without serifs will look better i would guess. For the gradient effect see the msdn page or google how on how to use it. Also, play around with the SmoothingMode and TextRenderingHint of the graphics object, HighQuality and Antialias should produce better looking results.

Jobo
  • 1,084
  • 7
  • 14