如何将XPS文件中的每个页面转换为C#中的图像?

时间:2010-09-25 19:59:08

标签: c# wpf image xps

有没有办法使用C#以编程方式将XPS文档中的每个页面转换为图像?

2 个答案:

答案 0 :(得分:10)

我在Josh Twist发布了这篇博文,似乎可以做你想做的事。

Cracking an XPS in WPF

在搜索网络时,有许多付费/试用程序声称这样做(我没有尝试过任何一个,所以我不能保证/列出其中任何一个)。我以为你想编写自己的代码。

这是博客文章的“肉”(浓缩):

Uri uri = new Uri(string.Format("memorystream://{0}", "file.xps"));
FixedDocumentSequence seq;

using (Package pack = Package.Open("file.xps", ...))
using (StorePackage(uri, pack))  // see method below
using (XpsDocument xps = new XpsDocument(pack, Normal, uri.ToString()))
{
    seq = xps.GetFixedDocumentSequence();
}

DocumentPaginator paginator = seq.DocumentPaginator;
Visual visual = paginator.GetPage(0).Visual;  // first page - loop for all

FrameworkElement fe = (FrameworkElement)visual;

RenderTargetBitmap bmp = new RenderTargetBitmap((int)fe.ActualWidth,
                          (int)fe.ActualHeight, 96d, 96d, PixelFormats.Default);
bmp.Render(fe);

PngBitmapEncoder png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(bmp));

using (Stream stream = File.Create("file.png"))
{
    png.Save(stream);
}

public static IDisposable StorePackage(Uri uri, Package package)
{
    PackageStore.AddPackage(uri, package);
    return new Disposer(() => PackageStore.RemovePackage(uri));
}

答案 1 :(得分:1)

请参阅接受的answer它真的有用(它也帮助了我)。我只想注意该解决方案中的一些非常重要的一点。

如果您正在实现自己的DocumentPaginator(在我的情况下),那么该代码将不起作用,因为我们不会从语句中引用您的特定Paginator

DocumentPaginator paginator = seq.DocumentPaginator;

将其投射到您自己的分页器也不起作用。

如果您拥有自己的Paginator,该解决方案也非常复杂。
所以我开发了一个简化的解决方案,该解决方案基于这个问题的公认解决方案,并且完全按照需要工作。

 // create your own paginator instead of this
 // this is my specific own implementation for DocumentPaginator class
 ReportPaginator paginator = new ReportPaginator(report);

 Visual visual = paginator.GetPage(0).Visual;  // first page - loop for all

 RenderTargetBitmap bmp = new RenderTargetBitmap((int)paginator.PageSize.Width, (int)paginator.PageSize.Height, 96d, 96d, PixelFormats.Default);
 bmp.Render(visual);

 PngBitmapEncoder png = new PngBitmapEncoder();
 png.Frames.Add(BitmapFrame.Create(bmp));

 using (MemoryStream sm = new MemoryStream())
 {
     png.Save(sm);
     return sm.ToArray();
 }