我刚刚开始尝试 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); }
}
}