Как преобразовать каждую страницу в файле XPS в изображение в C #? - PullRequest
7 голосов
/ 25 сентября 2010

Есть ли способ программно преобразовать каждую страницу в документе XPS в изображение с помощью C #?

Ответы [ 2 ]

10 голосов
/ 26 сентября 2010

Я наткнулся на это сообщение из Джоша Твиста , которое, кажется, делает то, что вы хотите.

Взлом XPS в 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 голос
/ 25 мая 2016

Пожалуйста, обратитесь к принятому ответу , это действительно полезно (это также помогло мне). Я просто хочу отметить один очень важный момент в этом решении.

если вы реализуете свой собственный DocumentPaginator (как в моем случае), тогда этот код не будет работать, поскольку мы не получим ссылку на ваш конкретный Paginator из оператора

DocumentPaginator paginator = seq.DocumentPaginator;

Приведение этого к вашему собственному paginator также не будет работать.

также это решение очень сложно, если у вас есть собственный 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();
 }
...