WPF MVVM Ghostscript.NET Viewer的适配器不会显示PDF页面作为ImageSource
问题描述:
我刚刚开始尝试使用Ghostscript.Net。我的目标是使GhostscriptViewer适应我的WPF MVVM模块化环境,但我无法在XAML Image控件中显示页面。我怀疑我的问题在于我对Ghostscript.Net的认识不足,或者不了解如何将图像参数绑定到图像控件。WPF MVVM Ghostscript.NET Viewer的适配器不会显示PDF页面作为ImageSource
在这个应用程序中,我使用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); }
}
}
答
好的。所以我想通了。我的解决方案并不完美;而通过PDF文档分页,页面方向不正确,但除此之外,它的工作原理。
的关键是创建一个BitmapImage的使用一个MemoryStream:
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应用程序。如果有人对更多细节感兴趣,我会发布更多。