2012-12-29 13 views
5

Szukałem i szukam tekstu rysunkowego z konturem na obrazy?Jak rysować tekst z konturem na obrazy?

Oto mój kod

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

i Jego spust

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

    } 

sprawdzić wynik Kod:

Messing resultnya Taki wynik brudząc, rozpakować i kolorem białym

ten czego chcę, i z wra pping?

This One

znalazłem w CodeProject ale nie szczęścia, jego wykorzystaniem C++. Oparty na someone in neowin i wypróbowany to one too ..

Ale wciąż nie szczęścia.

UPDATE:

Oto mój kod roboczych, dla kogo może trzeba go ... na podstawie z kodu Abdias Software (sprawdź odpowiedzi), robię małe zmiany (tam jakiś błąd w tych kodzie).

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

Mam edytowany tytuł. Zobacz, "[Czy w tytułach pytania powinny znaleźć się" znaczniki "?] (Http://meta.stackexchange.com/questions/19190/)", gdzie konsensus brzmi "nie, nie powinien". –

+0

@JohnSaunders dzięki człowiekowi ... – radiaku

Odpowiedz

25

Wystarczy, aby podsumować:

Definiowanie GraphicPath a następnie użyć DrawPath zwrócić przedstawioną wersję tekstu, FillPath narysować wersję wypełniony.

Dla drugiego zdjęcia z kobietą, druga (wypełniona) wersja jest narysowana jako pierwsza z niewielkim przesunięciem.

Do użytku gradientowego LinearGradientBrush dla brush. Grubość konturu określa grubość pisaka.

Do owijania określić StringFormat i używać Rectangle zdefiniować obszar, który ma tekst być w.

Aby wyśrodkować tekst można zdefiniować prostokąt mieć taką samą szerokość jak obraz, a następnie ustawić strformat.Alignment do Center.

UPDATE: Aby powtórzyć tekst w drugim obrazie można użyć tego kodu:

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

To będzie produkować ten wynik:

Resulting image

do wytworzenia dodatkowej "cień" po prostu przetłumacz najpierw: g, wypełnij, a następnie usuń tłumaczenie.

Użyto tutaj FromHtml, ponieważ wybrałem kolory ze zdjęcia i byłem leniwy, by się nawrócić. Po prostu użyj Color.FromARGB() lub ustalonego koloru - jak chcesz.

wersja 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() 
+0

Dzięki człowieku ... Właśnie uratowałeś dzień ..: D – radiaku

+0

jest jakiś błąd w kodzie, sprawdź moją zaktualizowaną wersję ..., nie wiem dlaczego, ale w visual studio C# 2008 express ... pojawia się błąd. W każdym razie dzięki jeszcze raz ... :) – radiaku

+0

Napisałem to w VB pierwotnie dla tego posta - coś się zepsuło podczas tłumaczenia na C# Myślę, że. Sprawdzę, dzięki :) – K3N

2

Prostym sposobem na uzyskanie "lepszych" wyników może być dwukrotne narysowanie tekstu. Najpierw narysuj cień, na przykład kilka pikseli po prawej i na dole, jeśli chcesz uzyskać klasyczny efekt cieniowania, w szarym kolorze. Możesz także rozważyć użycie innej czcionki, a każda czcionka bez szeryfów będzie wyglądać lepiej, jak sądzę. Aby uzyskać efekt gradientu, patrz: msdn page lub google, jak go używać. Odtwarzanie obiektów SmoothingMode i TextRenderingHint obiektu graficznego, HighQuality i Antialias powinno przynieść lepsze rezultaty.

Powiązane problemy