0

我刚刚开始尝试 Ghostscript.Net。我的目标是使 GhostscriptViewer 适应我的 WPF MVVM 模块化环境,但我无法在 XAML 图像控件中显示页面。我怀疑我的问题在于我对 Ghostscript.Net 的了解不足或不了解如何将图像参数绑定到图像控件。

在这个应用程序中,我将 Prism 与 UnityContainer 一起使用。PdfViewModel 中的 PdfPageImage 属性绑定到视图 XAML 中的图像控件。在 _viewer_displaypage 方法中进行的转换为 PdfPageImage 提供了 System.Windows.Interop.InteropBitmap 类型的对象。我在想 RaisePropertyChangedEvent 方法会导致控件使用 ImageSource 对象进行更新。

            <Image x:Name="PdfDocumentImage" Grid.Column="1" Grid.Row="0" 
                   Source="{Binding PdfPageImage}"
                   Height="100"
                   Width="100">
            </Image>

    public class PdfViewModel : ViewModelBase, IPdfViewModel
{
    private readonly IBitmapToImageSourceConverter _imageSourceConverter;

    private readonly GhostscriptViewer _ghostscriptViewer;
    private readonly GhostscriptVersionInfo _gsVersion =
        GhostscriptVersionInfo.GetLastInstalledVersion(GhostscriptLicense.GPL | 
            GhostscriptLicense.AFPL, GhostscriptLicense.GPL);

    private ImageSource _pdfPageImage;
    public ImageSource PdfPageImage
    {
        get => _pdfPageImage;

        set
        {
            if (value == _pdfPageImage) return;
            _pdfPageImage = value;
            RaisePropertyChangedEvent(nameof(PdfPageImage));
        }
    }

    public PdfViewModel(IPdfView view,
        IEventAggregator eventAggregator,
        IBitmapToImageSourceConverter imageSourceConverter,
        GhostscriptViewer ghostscriptViewer)
        : base(view)
    {
        _ghostscriptViewer = ghostscriptViewer;
        _imageSourceConverter = imageSourceConverter;

        _ghostscriptViewer.DisplayPage += _viewer_DisplayPage;

        eventAggregator.GetEvent<PdfDocumentOpenedEvent>().Subscribe(OpenPdfDocument, ThreadOption.UIThread);
    }

    private void _viewer_DisplayPage(object sender, GhostscriptViewerViewEventArgs e)
    {
        PdfPageImage = _imageSourceConverter.ImageSourceForBitmap(e.Image);
    }

    private void OpenPdfDocument(string path)
    {
        _ghostscriptViewer.Open(path, _gsVersion, false);
    }
}

    public class BitmapToImageSourceConverter : IBitmapToImageSourceConverter
{
    [DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool DeleteObject(IntPtr hObject);
    public ImageSource ImageSourceForBitmap(Bitmap bmp)
    {
        var handle = bmp.GetHbitmap();
        try
        {
            return Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
        }
        finally { DeleteObject(handle); }
    }
}
4

1 回答 1

1

好的。所以我想通了。我的解决方案并不完美;翻阅pdf文档时,页面方向不正确,但除此之外,它可以工作。

关键是在创建 BitmapImage 时使用内存流:

        public static BitmapImage ConvertBitmapToImage(System.Drawing.Image image)
    {
        using (MemoryStream memoryStream = new MemoryStream())
        {
            image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
            memoryStream.Position = 0;

            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            memoryStream.Seek(0, SeekOrigin.Begin);
            bitmapImage.StreamSource = memoryStream;
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.EndInit();

            return bitmapImage;
        }
    }

进行了许多其他修改以使 Ghostscrip.NET 查看器在我的 WPF MVVM 应用程序中工作。如果有人对更多细节感兴趣,我会发布更多。

于 2017-07-23T22:41:06.427 回答