4

We are working on an Optical Character Recognition system and i want to compare how different renderers render text. I want to make a simple program that creates an image, writes some text on it with different fonts, sizes and styles and saves it to a .png file(I want to have all sizes, fonts styles i need in one file so they are easy to compare). I've managed to do it with GDI and GDI+ renderers using Bitmap. Now i'm trying to do the same thing in a WPF application, as I've heard rendering text there is different. Is it possible to use BitmapImage for that? Coming from Windows Forms I presume this problem should be pretty simple but i just can't seem to do it in WPF.

This is a simplified version of how i did it with GDI+ Renderer:

public void CreateAndSave()
{
    Bitmap bitmap = new Bitmap(500, 500, PixelFormat.Format24bppRgb);
    Graphics g = Graphics.FromImage(bitmap);
    g.Clear(Color.White);
    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
    g.DrawString("sample text", font, brush, x, y);
    bitmap.Save(fileName);
}

Is there any similar way of doing this with WPF?

2 Answers 2

3

Such as methods like "DrawString" are costly in WPF. Instead of that doing that, you can create a canvas/grid and put the text box or labels etc. and then you can render that canvas/grid. You can use that code:

public void ConvertToBitmapSource(UIElement element)
{
    var target = new RenderTargetBitmap(
        (int)element.RenderSize.Width, (int)element.RenderSize.Height,
        96, 96, PixelFormats.Pbgra32);
    target.Render(element);

    var encoder = new PngBitmapEncoder();
    var outputFrame = BitmapFrame.Create(target);
    encoder.Frames.Add(outputFrame);

    using (var file = File.OpenWrite("TestImage.png"))
    {
        encoder.Save(file);
    }
}
Sign up to request clarification or add additional context in comments.

9 Comments

Thank you for your answer. This idea might work. The problem i have now is that i want a .png with a lot of different fonts and sizes and i would have to create a lot of labels to do that. Also when i use this method the text rendered in the .png is not the same as on the actual running application. That might be caused by the background being transparent. Is there a quick way of setting the background color of RenderTargetBitmap to white, or do i have to set every bit to white?
One way to that if you use a grid/canvas as UIElement, try to set the background of it as White. It will work
I changed the background to white, but it appears that the background wasn't causing bad quality of text. Maybe if it renders the whole element onto a RenderTargetBitmap it doesn't care about how the text was rendered earlier. I also tried to use this method on a single label but it still isn't doing it.
So text quality depends on also resolution and dpi. You can arrange them but file size will be greater
I set the dpi to 120 to match my systems dpi and its acceptably similar to the original. Thank you for help.
|
0

Use the FormattedText class to build a Geometry object, take an example from here: https://msdn.microsoft.com/en-us/library/system.windows.media.formattedtext.buildgeometry(v=vs.110).aspx

Then, use one of the BitmapEncoder classes to save the Geometry object you've built. Look at that example: https://stackoverflow.com/a/9081295/3730455

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.