如何使用图像轮廓绘制文本?

时间:2012-12-29 00:30:00

标签: c# winforms visual-studio-2008

我一直在寻找并在图像上寻找带有轮廓的绘图文字?

这是我的代码

    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();
    }

及其触发器

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

    }

检查代码结果:

Messing resultnya 这样的混乱结果,UNWRAPPED和白色

这就是我想要的,还有包装?

This One

我在CodeProject找到了,但没有运气,它使用的是C ++。基于someone in neowin并尝试了此one too ..

但仍然没有运气。

更新

这里是我的工作代码,对于谁可能需要它...基于Abdias Software的代码(检查答案),我做了一些小改动(这些代码中有一些错误)。

        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();
    }

2 个答案:

答案 0 :(得分:24)

总结一下:

定义GraphicPath,然后使用DrawPath绘制文本的概述版本FillPath以绘制填充版本。

对于女性的第二个图像,第一个(填充的)版本首先以较小的偏移量绘制。

对于LinearGradientBrush的渐变使用brush。轮廓的厚度由笔的厚度定义。

包装定义StringFormat并使用Rectangle定义您希望文本所在的区域。

要使文字居中,您可以将矩形定义为与图像具有相同的宽度,然后将strformat.Alignment设置为Center

更新:要复制第二张图片中的文字,您可以使用以下代码:

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

这将产生以下结果:

Resulting image

要制作额外的“影子”,只需首先翻译g,然后删除填充,然后删除翻译。

我在这里使用FromHtml,因为我从您的图片中选择颜色并且懒得转换。只需使用Color.FromARGB()或固定颜色即可。

VB版:

    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()

答案 1 :(得分:2)

获得“更好”结果的简单方法可能是两次绘制文本。首先绘制阴影,例如,如果您想要灰色的经典阴影外观,则向右和向下绘制一些像素。您可能还想考虑使用不同的字体,任何没有衬线的字体看起来会更好我猜。 有关渐变效果,请参阅msdn page或谷歌如何使用它。 此外,使用图形对象的SmoothingModeTextRenderingHint,HighQuality和Antialias应该会产生更好看的结果。