Create text on top of an existing image file?

So, I did it in WinForms.NET 3.5 ... I am using WPF.NET 4.0 ... and I cannot figure out how to do this.

This is what I did on Windows.NET 3.5

using (Bitmap eventImg = new Bitmap("input.png")) { Graphics eventGfx = Graphics.FromImage(eventImg); buildText(eventGfx, this.event1.Text); eventImg.Save("output.png", ImageFormat.Png); eventGfx.Dispose(); } 

The above code took an existing image to "input.png", created a new image from it, wrote text from it, and then saved the new image to "output.png". The text was written using the following function:

 private void buildText(Graphics graphic, string text) { if (text.Length == 0) { return; } FontStyle weight = FontStyle.Regular; switch (this.font_style) { case "regular": weight = FontStyle.Regular; break; case "bold": weight = FontStyle.Bold; break; case "italic": weight = FontStyle.Italic; break; case "underline": weight = FontStyle.Underline; break; case "strikeout": weight = FontStyle.Strikeout; break; } using (Font font = new Font(this.font_family, this.font_size, weight, GraphicsUnit.Pixel)) { Rectangle rect = new Rectangle(this.left, this.top, this.width, this.height); Brush brush = new SolidBrush(Color.FromArgb(this.font_color)); StringFormat format = new StringFormat(); switch (this.align_x) { case "left": format.Alignment = StringAlignment.Near; break; case "right": format.Alignment = StringAlignment.Far; break; default: format.Alignment = StringAlignment.Center; break; } switch (this.align_y) { case "top": format.LineAlignment = StringAlignment.Near; break; case "bottom": format.LineAlignment = StringAlignment.Far; break; default: format.LineAlignment = StringAlignment.Center; break; } graphic.TextRenderingHint = TextRenderingHint.AntiAlias; graphic.DrawString(text, font, brush, rect, format); } } 

However, since System.Drawing does not exist in WPF.NET 4.0, I can no longer use these functions. How will I do what I'm trying to do in WPF.NET 4.0? I went to the code below to take the first step of creating an image based on an old image:

 using (var fileStream = new FileStream(@"z:\ouput.png", FileMode.Create)) { BitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(new Uri(@"z:\input.png"))); encoder.Save(fileStream); } 
+4
source share
3 answers

After reading the answers and comments, I thought you could appreciate a more comprehensive solution. Here is a small method that does this work:

 public static void WriteTextToImage(string inputFile, string outputFile, FormattedText text, Point position) { BitmapImage bitmap = new BitmapImage(new Uri(inputFile)); // inputFile must be absolute path DrawingVisual visual = new DrawingVisual(); using (DrawingContext dc = visual.RenderOpen()) { dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight)); dc.DrawText(text, position); } RenderTargetBitmap target = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight, bitmap.DpiX, bitmap.DpiY, PixelFormats.Default); target.Render(visual); BitmapEncoder encoder = null; switch (Path.GetExtension(outputFile)) { case ".png": encoder = new PngBitmapEncoder(); break; // more encoders here } if (encoder != null) { encoder.Frames.Add(BitmapFrame.Create(target)); using (FileStream outputStream = new FileStream(outputFile, FileMode.Create)) { encoder.Save(outputStream); } } } 

You would use this method with a FormattedText object and position:

 FormattedText text = new FormattedText( "Hello", CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface("Segeo UI"), 20, Brushes.Red); WriteTextToImage( @"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg", "Desert.png", text, new Point(10, 10)); 

EDIT: if you want to draw text horizontally and vertically with respect to a specific rectangle, you can replace the position parameter with that rectangle and two alignment parameters and calculate the text position as follows:

 public static void WriteTextToImage(string inputFile, string outputFile, FormattedText text, Rect textRect, HorizontalAlignment hAlign, VerticalAlignment vAlign) { BitmapImage bitmap = new BitmapImage(new Uri(inputFile)); DrawingVisual visual = new DrawingVisual(); Point position = textRect.Location; switch (hAlign) { case HorizontalAlignment.Center: position.X += (textRect.Width - text.Width) / 2; break; case HorizontalAlignment.Right: position.X += textRect.Width - text.Width; break; } switch (vAlign) { case VerticalAlignment.Center: position.Y += (textRect.Height - text.Height) / 2; break; case VerticalAlignment.Bottom: position.Y += textRect.Height - text.Height; break; } using (DrawingContext dc = visual.RenderOpen()) { dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight)); dc.DrawText(text, position); } RenderTargetBitmap target = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight, bitmap.DpiX, bitmap.DpiY, PixelFormats.Default); target.Render(visual); BitmapEncoder encoder = null; switch (Path.GetExtension(outputFile)) { case ".png": encoder = new PngBitmapEncoder(); break; case ".jpg": encoder = new JpegBitmapEncoder(); break; } if (encoder != null) { encoder.Frames.Add(BitmapFrame.Create(target)); using (FileStream outputStream = new FileStream(outputFile, FileMode.Create)) { encoder.Save(outputStream); } } } 

Now you can use the method as follows:

 WriteTextToImage(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg", "Desert.png", text, new Rect(80, 50, 430, 200), HorizontalAlignment.Center, VerticalAlignment.Center); 
+8
source

You can use a grid or any other panel that suits your needs as follows.

 <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Image x:name="My image" .. bind it to the bintmap Grid.row="0" Grid.colomn="0"/> <TextBlock x:name="MyText" Text="....." Grid.row="0" Grid.colomn="0"/> </Grid> 

text and image are drawn in the same space in the grid, and you can manipulate the alignment anyway, as you like

+1
source

In WPF, you are not allowed to use Graphics because wpf offers a new tec. for this. Graphics are from older Windows APIs, but WPF uses DirectX. As an example, WPF no longer works with pixels, etc.

http://msdn.microsoft.com/de-de/library/system.windows.media.drawingcontext.aspx

-4
source

All Articles