【问题标题】:WPF image vector format export (XPS?)WPF 图像矢量格式导出(XPS?)
【发布时间】:2011-09-23 08:25:45
【问题描述】:

我们的工具允许导出为 PNG,效果非常好。 现在,我想将导出添加到一些矢量格式。我试过XPS,但结果一点也不令人满意。

看看比较http://www.jakubmaly.cz/xps-vs-png.png。 左边的图片来自 XPS 导出,右边的图片来自 PNG 导出,XPS 图片在 XPS Viewer 中打开并放大 100% 时明显模糊。

我是否缺少任何设置或为什么会这样?

谢谢, 雅库布。

可以在此处找到示例 xps 输出:http://www.jakubmaly.cz/files/a.xps。 这是执行 XPS 导出的代码:

if (!boundingRectangle.HasValue)
{
    boundingRectangle = new Rect(0, 0, frameworkElement.ActualWidth, frameworkElement.ActualHeight);
}

// Save current canvas transorm
Transform transform = frameworkElement.LayoutTransform;
// Temporarily reset the layout transform before saving
frameworkElement.LayoutTransform = null;


// Get the size of the canvas
Size size = new Size(boundingRectangle.Value.Width, boundingRectangle.Value.Height);
// Measure and arrange elements
frameworkElement.Measure(size);
frameworkElement.Arrange(new Rect(size));

// Open new package
System.IO.Packaging.Package package = System.IO.Packaging.Package.Open(filename, FileMode.Create);
// Create new xps document based on the package opened
XpsDocument doc = new XpsDocument(package);
// Create an instance of XpsDocumentWriter for the document
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
// Write the canvas (as Visual) to the document
writer.Write(frameworkElement);
// Close document
doc.Close();
// Close package
package.Close();

// Restore previously saved layout
frameworkElement.LayoutTransform = transform;

【问题讨论】:

  • 您可能错过了某处的设置 - XPS 非常有能力产生清晰的输出。您能否在某处发布实际导出的 xps,并提供有关您如何导出以及您使用的 XPS 查看器的更多信息?
  • 我添加了生成 XPS 的实际代码以及指向结果的链接。我正在使用 Windows 7 内置的 XPS 查看器。我的目标是得到一个漂亮而清晰的矢量PDF,如果有其他方法,请给我提示。

标签: wpf image png export xps


【解决方案1】:

有趣(和烦人)的问题 - 您可能想查看从 Jo0815Printing XpsDocument causes resampled images (96dpi?) - FixedDocument prints sharp 的冗长回答,引用 Microsoft 支持响应 - 一些摘录:

来自 WPF 的一些矢量特征无法在我们的 GDI 代码中进行仿真,并且 我们求助于将场景的子集转换为 GDI 位图。这些 位图是模糊缩放的原因。

[...]

这些位图是模糊缩放的原因。问题是 WPF 以错误的分辨率被光栅化为位图。 打印路径旨在将不支持的功能光栅化为 位图,但它应该以设备分辨率进行。取而代之的是 光栅化始终以 96dpi 进行。这对屏幕来说很好 但会为 600dpi 打印机产生模糊的输出[强调我的]

请注意,后者当然也适用于现在更高 DPI 的屏幕,我已经多次遇到过这样的模糊 - 您是否碰巧使用了高 DPI 显示器?

现在,显然微软并没有完全控制这方面的设备:

此外,该问题仅在打印 XPS 时出现,而不是 直接打印 XAML 时出现问题。我很确定有 某处的文档说 XPS 将以设备分辨率打印。 [...] 这是我们 计划在下一个版本的产品中改进,但不是针对 Win 7。 问题是在打印 XAML 时它会正确呈现 600dpi 的图像,但在打印 XPS 时仍会渲染图像 96dpi。 由于 XAML 在打印之前已转换为 XPS,因此看起来 很奇怪,一种打印 XPS 的方法会产生不同的结果 到另一种打印 XPS 的方法。 [强调我的]

[...]

没有用于配置 XPS 文档编写器 DPI 的 UI。如果你以后 以与作者不同的 DPI 打印生成的 XPS 文档 内部默认值可能会导致位图内容的结果不佳。使用 GDI 您可以控制最终 DPI 的打印机,您的最终目的地是 通常是纸张 - 没有机会重新打印文档。

结论

总之,如果您的用例允许这样做,我仍然会尝试在 Néstor Sánchez' approach (+1) 内调整 PrintTicket.PageResolution Property(尽管我远程记得在某处读过,但这也没有任何效果); Using the XPS Rasterization Service 中的 Bitmap Resolution and Pixel Format 部分证实了他在 FixedDocument 中遇到的问题:

固定页面的 XPS 光栅化对象必须知道分辨率为 将呈现哪个页面。 XPSDrv 过滤器指定了这个 分辨率,以每英寸点数 (DPI) 为单位,作为输入参数 [...] 例如,如果显示设备具有分辨率 600 DPI,固定页面描述标准信纸大小的页面, 整个页面的位图图像具有以下尺寸[...]

解决方法

作为一种潜在的解决方法,您可能想探索 alexandrud 对相关问题 How to convert a XPS file to an image in high quality (rather than blurry low resolution)? 的解决方案,该解决方案建议使用 xps2imgXPS(XML 纸张规范)文档到一组图像转换实用程序。 特别是它允许指定图像大小或 DPI,这可能会有所帮助,具体取决于依次应用的打印路径解决方案。

祝你好运!

【讨论】:

    【解决方案2】:

    我也遇到过类似的问题。当通过 FixedDocument 传递给 XPS 时,我的图像非常模糊。 解决办法是直接把图片写入XPS...

    /// <summary>
    /// Saves the supplied visual Source, within the specified Bounds, as XPS in the specified File-Name.
    /// Returns error message or null when succeeded.
    /// </summary>
    public static string SaveVisualAsXPS(Visual Source, Size Bounds, string FileName)
    {
        string ErrorMessage = null;
    
        try
        {
            using (var Container = Package.Open(FileName, FileMode.Create))
            {
                using (var TargetDocument = new XpsDocument(Container, CompressionOption.Maximum))
                {
                    var Writer = XpsDocument.CreateXpsDocumentWriter(TargetDocument);
                    var Ticket = GetPrintTicketFromPrinter();
                    if (Ticket == null)
                        return "No printer is defined.";
    
                    Ticket.PageMediaSize = new PageMediaSize(Bounds.Width, Bounds.Height);
                    var SourceVisual = Source;
                    Writer.Write(SourceVisual, Ticket);
                }
            }
        }
        catch (Exception Problem)
        {
            ErrorMessage = "Cannot export document to XPS.\nProblem: " + Problem.Message;
        }
    
        return ErrorMessage;
    }
    

    提供具有精确宽度和高度的打印票可避免缩放(在我的情况下这是我想要的)。 从以下示例中获取函数: http://msdn.microsoft.com/en-us/library/system.printing.printticket.aspx

    【讨论】:

    • 我也添加了我的代码。我的和你的输出之间没有明显的区别。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    相关资源
    最近更新 更多