【问题标题】:How to convert a XPS file to an image in high quality (rather than blurry low resolution)?如何将 XPS 文件转换为高质量的图像(而不是模糊的低分辨率)?
【发布时间】:2011-09-27 10:50:17
【问题描述】:

我正在尝试使用 WPF 转换 XPS。

想法是这些图像可以用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文档,我正在尝试转换图像 Please download test.xps

【问题讨论】:

  • 您正在尝试以 1800 dpi 进行渲染。这完全是矫枉过正 - 任何超过 300 dpi 的东西都会过分,除非你打算在屏幕上放大。
  • 你是对的,300 dpi 只是在尝试不同的值有什么建议吗?
  • 如果你愿意离线(和跨平台),那么你可以使用ghostscript,它在以后的版本中支持xps。见:ghostscript.com/GPL_Ghostscript_8.61.html
  • 您是否有用于生成模糊图像的示例 xps 文档?我得到了很好的清晰图像。
  • 是的,我附上了文件!。谢谢。

标签: c# wpf silverlight xps rendertargetbitmap


【解决方案1】:

sourceforge.net 上有一个名为 xps2img 的项目,可以将 xps 转换为图像。它是用 C# 制作的,还包含源代码。看看这个。它会帮助你实现你想要的。

http://sourceforge.net/projects/xps2img/files/

【讨论】:

  • +1 这个是免费的,完成了工作!不包括水印或顽皮的东西。在我的情况下,我从 Word 的 docx 转换,转换为 xps 以某种方式提供比 pdf 更好的字体渲染(然后是图像)。
【解决方案2】:

我在这篇文章和许多其他文章中看到人们在将 DocumentPage 转换为 Image 并将其保存在 HDD 上时遇到问题。 此方法从文档查看器中获取所有页面并将它们作为 jpg 图像保存在 HDD 上。

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();
                }
            }
        }
    }

【讨论】:

    【解决方案3】:

    现在可以使用基于 xps2img 的 nuget 包: https://www.nuget.org/packages/xps2img/

    此处提供的 API: https://github.com/peters/xps2img#usage

    【讨论】:

      【解决方案4】:
          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();
              }
          }
      

      【讨论】:

      • @TheLethalCoder 是 RenderTargetBitmap 构造函数的第三和第四个参数给它resulation,但是我们也需要增加初始大小(第一个和第二个)否则图像会被放大。归根结底,它起作用了,这才是最重要的......
      猜你喜欢
      • 1970-01-01
      • 2017-07-01
      • 1970-01-01
      • 2014-11-20
      • 2016-10-13
      • 2011-11-22
      • 2014-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多