位图图形与WinForm控制图形

时间:2015-02-09 13:58:39

标签: c# wpf winforms bitmap gdi+

我只使用名为PdfiumViewerPdfium .NET端口。它只是在WinForm控件中呈现时效果很好但是当我尝试在Bitmap上呈现它以在WPF窗口中显示(甚至保存到磁盘)时,渲染的文本有问题。

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

值得注意的是,我在Graphics对象上测试了几乎所有可能的选项,包括TextContrastTextRenderingHintSmoothingModePixelOffsetMode ,...

导致此问题的Bitmap对象上缺少哪些配置?

enter image description here

修改2

经过大量搜索后,正如@BoeseB所提到的,我发现Pdfium通过提供第二种渲染方法FPDF_RenderPageBitmap来渲染设备句柄和位图的方式不同,目前我正在努力将其原生BGRA位图格式转换为托管Bitmap

修改

TextRenderingHint的不同模式 enter image description here

同时尝试Application.SetCompatibleTextRenderingDefault(false)没有明显区别。

1 个答案:

答案 0 :(得分:1)

不是你的issue吗? 查看最近的fix。 如您所见,存储库所有者提交了较新版本的PdfiumViewer。现在你可以这样写:

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

以下是将Image转换为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;
    }
}