Как преобразовать файл XPS в изображение с высоким качеством (а не с размытым низким разрешением)?
Я пытаюсь конвертировать XPS с WPF.
Идея заключается в том, что эти изображения могут быть загружены с Silverlight 4, для этого я использую следующий код:
// XPS Document
XpsDocument xpsDoc = new XpsDocument(xpsFileName, System.IO.FileAccess.Read);
FixedDocumentSequence docSeq = xpsDoc.GetFixedDocumentSequence();
// The number of pages
PageCount = docSeq.References[0].GetDocument(false).Pages.Count;
DocumentPage sizePage = docSeq.DocumentPaginator.GetPage(0);
PageHeight = sizePage.Size.Height;
PageWidth = sizePage.Size.Width;
// Scale dimensions from 96 dpi to 600 dpi.
double scale = 300/ 96;
// Convert a XPS page to a PNG file
for (int pageNum = 0; pageNum < PageCount; pageNum++)
{
DocumentPage docPage = docSeq.DocumentPaginator.GetPage(pageNum);
BitmapImage bitmap = new BitmapImage();
RenderTargetBitmap renderTarget =
new RenderTargetBitmap((int)(scale * (docPage.Size.Height + 1)),
(int)(scale * (docPage.Size.Height + 1)),
scale * 96,
scale * 96, PixelFormats.Pbgra32);
renderTarget.Render(docPage.Visual);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTarget));
FileStream pageOutStream = new FileStream(name + ".Page" + pageNum + ".png", FileMode.Create, FileAccess.Write);
encoder.Save(pageOutStream);
pageOutStream.Close();
Этот код взят из http://xpsreader.codeplex.com/ проекта для преобразования документа XPS. работает отлично! Но проблема в том, что изображение имеет низкое разрешение и размыто. Я исследовал и обнаружил, что RenderTargetBitmap и нашел на этой странице: http://www.codeproject.com/Questions/213737/Render-target-bitmap-quality-issues
Проблема здесь в том, что у вас нет аппаратного рендеринга RenderTargetBitmap.
Одним из решений является использование DirectX с WPF для этого, но я не нашел четкого примера, чтобы показать мне правильный способ сделать это.
Я ценю предложения. Заранее спасибо.
Обновление: я приложил документ XPS, я пытаюсь преобразовать изображение Пожалуйста, скачайте test.xps
3 ответа
В этом посте и во многих других я видел, что у людей возникают проблемы с преобразованием DocumentPage в изображение и сохранением его на жестком диске. Этот метод извлекает все страницы из средства просмотра документов и сохраняет их на жестком диске в виде изображений jpg.
public void SaveDocumentPagesToImages(IDocumentPaginatorSource document, string dirPath)
{
if (string.IsNullOrEmpty(dirPath)) return;
if (dirPath[dirPath.Length - 1] != '\\')
dirPath += "\\";
if (!Directory.Exists(dirPath)) return;
MemoryStream[] streams = null;
try
{
int pageCount = document.DocumentPaginator.PageCount;
DocumentPage[] pages = new DocumentPage[pageCount];
for (int i = 0; i < pageCount; i++)
pages[i] = document.DocumentPaginator.GetPage(i);
streams = new MemoryStream[pages.Count()];
for (int i = 0; i < pages.Count(); i++)
{
DocumentPage source = pages[i];
streams[i] = new MemoryStream();
RenderTargetBitmap renderTarget =
new RenderTargetBitmap((int)source.Size.Width,
(int)source.Size.Height,
96, // WPF (Avalon) units are 96dpi based
96,
System.Windows.Media.PixelFormats.Default);
renderTarget.Render(source.Visual);
JpegBitmapEncoder encoder = new JpegBitmapEncoder(); // Choose type here ie: JpegBitmapEncoder, etc
encoder.QualityLevel = 100;
encoder.Frames.Add(BitmapFrame.Create(renderTarget));
encoder.Save(streams[i]);
FileStream file = new FileStream(dirPath + "Page_" + (i+1) + ".jpg", FileMode.CreateNew);
file.Write(streams[i].GetBuffer(), 0, (int)streams[i].Length);
file.Close();
streams[i].Position = 0;
}
}
catch (Exception e1)
{
throw e1;
}
finally
{
if (streams != null)
{
foreach (MemoryStream stream in streams)
{
stream.Close();
stream.Dispose();
}
}
}
}
На sourceforge.net есть проект xps2img, который преобразует xps в изображение. Он сделан на C# и также содержит исходный код. Проверьте это. Это поможет вам достичь того, что вы хотите.
Теперь доступен пакет nuget на основе xps2img: https://www.nuget.org/packages/xps2img/
API доступен здесь: https://github.com/peters/xps2img
private IList<byte[]> GetTifPagesFromXps(string xXpsFileName, double xQuality)
{
using (var xpsDoc = new XpsDocument(xXpsFileName, FileAccess.Read))
{
var docSeq = xpsDoc.GetFixedDocumentSequence();
var tifPages = new List<byte[]>();
for (var i = 0; i < docSeq.DocumentPaginator.PageCount; i++)
{
using (var docPage = docSeq.DocumentPaginator.GetPage(i))
{
var renderTarget = new RenderTargetBitmap((int)(docPage.Size.Width * xQuality), (int)(docPage.Size.Height * xQuality), 96 * xQuality, 96 * xQuality, PixelFormats.Default);
renderTarget.Render(docPage.Visual);
var jpegEncoder = new JpegBitmapEncoder { QualityLevel = 100 };
jpegEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
byte[] buffer;
using (var memoryStream = new MemoryStream())
{
jpegEncoder.Save(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
buffer = memoryStream.GetBuffer();
}
tifPages.Add(buffer);
}
}
xpsDoc.Close();
return tifPages.ToArray();
}
}