4

I'm just using a .NET port of Pdfium named PdfiumViewer. It just works very well once rendered in the WinForm controls but when I try to render it on a Bitmap to show in the WPF windows (or even saving to disk) the rendered text has problem.

var pdfDoc = PdfiumViewer.PdfDocument.Load(FileName);
int width = (int)(this.ActualWidth - 30) / 2;
int height = (int)this.ActualHeight - 30;            

var bitmap = new System.Drawing.Bitmap(width, height);

var g = System.Drawing.Graphics.FromImage(bitmap);

g.FillRegion(System.Drawing.Brushes.White, new System.Drawing.Region(
    new System.Drawing.RectangleF(0, 0, width, height)));

pdfDoc.Render(1, g, g.DpiX, g.DpiY, new System.Drawing.Rectangle(0, 0, width, height), false);

// Neither of these are readable
image.Source = BitmapHelper.ToBitmapSource(bitmap);
bitmap.Save("test.bmp");

// Directly rendering to a System.Windows.Forms.Panel control works well
var controlGraphics = panel.CreateGraphics(); 
pdfDoc.Render(1, controlGraphics, controlGraphics.DpiX, controlGraphics.DpiY,
    new System.Drawing.Rectangle(0, 0, width, height), false);

It's notable to say that I tested almost every possible options on the Graphics object including TextContrast,TextRenderingHint,SmoothingMode,PixelOffsetMode, ...

Which configurations I'm missing on the Bitmap object that cause this?

enter image description here

Edit 2

After lots of searching and as @BoeseB mentioned I just found that Pdfium render device handle and bitmaps differently by providing a second render method FPDF_RenderPageBitmap and currently I'm struggling to convert its native BGRA bitmap format to managed Bitmap.

Edit

Different modes of TextRenderingHint enter image description here

Also tried Application.SetCompatibleTextRenderingDefault(false) with no noticeable difference.

Mohsen Afshin
  • 13,273
  • 10
  • 65
  • 90
  • 1
    On my splash screen project i had a similar problem rendering text on to an image. It helped to set the TextRenderingHint. You already tried all different settings? how does the result look for the different settings? – BoeseB Feb 09 '15 at 14:08
  • 1
    Please describe the text rendering problem, or better yet include a link to a screenshot of the error. Also, I would just note that WPF always draws bitmaps scaled to their DPI. Since you have not explicitly set the DPI in your code above, there may be a mistmatch between the Bitmap's DPI and your display's DPI. – RogerN Feb 09 '15 at 14:19
  • Also what happens if you use Application.SetCompatibleTextRenderingDefault(false); Before displaying the Control? I guess the Control uses GDI+ (graphics.DrawString) to display the Text and your draw to bitmap uses GDI (TextRenderer.DrawText) see this Answer http://stackoverflow.com/a/23230570/4369295 – BoeseB Feb 09 '15 at 14:28
  • @BoeseB, please see my edit. Also I checked that both Control and Bitmap had the same 96 vertical and horizontal resolutions. – Mohsen Afshin Feb 09 '15 at 18:22
  • 2
    The quality of the images in the question are too poor to draw conclusions. It fact that the "bad" images have text that is much bolder strongly fits a pattern however. This happens when text is rendered on a transparent background. The text renderer doesn't support alpha blending, it anti-aliases from black text to a black background. That completely destroys the visual effect, letters just turn in a blob of black pixels. How that could have happened is very unclear, you definitely make an effort to make the background pixels white. Normally done with Graphics.Clear() btw. – Hans Passant Feb 09 '15 at 18:52
  • Sry i am clueless. I looked into the sources of PdfiumViewer and .NetFramework. The managed part has only one diffence at the calls to the native Methods to get a graphics handle. Maybe you should switch to another viewer for wpf. – BoeseB Feb 10 '15 at 12:42
  • @BoeseB, just asked another more correct question http://stackoverflow.com/questions/28448474/render-pdf-page-to-bitmap-using-pdfium – Mohsen Afshin Feb 11 '15 at 07:11

1 Answers1

1

Isn't it your issue ? Look recent fix for it. As you can see, repository owner commited newer version of PdfiumViewer. Now you can write this way:

var pdfDoc = PdfDocument.Load(@"mydoc.pdf");
var pageImage = pdfDoc.Render(pageNum, width, height, dpiX, dpiY, isForPrinting);
pageImage.Save("test.png", ImageFormat.Png);

// to display it on WPF canvas
BitmapSource source = ImageToBitmapSource(pageImage);
canvas.DrawImage(source, rect);     // canvas is instance of DrawingContext

Here is a popular approach to convert Image to ImageSource

BitmapSource ImageToBitmapSource(System.Drawing.Image image)
{
    using(MemoryStream memory = new MemoryStream())
    {
        image.Save(memory, ImageFormat.Bmp);
        memory.Position = 0;
        var source = new BitmapImage();
        source.BeginInit();
        source.StreamSource = memory;
        source.CacheOption = BitmapCacheOption.OnLoad;
        source.EndInit();

        return source;
    }
}
shameleo
  • 344
  • 2
  • 13
  • @MohsenAfshin I added some code samples. I tested it with PdfiumViewer v 1.4.0.0 and it works like a charm. Much faster and prettier than with ghostscrypt. Guess your issue is solved. – shameleo Feb 14 '15 at 21:47