我们的工具允许导出到PNG,效果非常好。 现在,我想将导出添加到某种矢量格式。我尝试了XPS,但结果并不令人满意。
查看比较http://www.jakubmaly.cz/xps-vs-png.png。 左边的图片来自XPS导出,PNG导出右边的图片,XPS图片在XPS Viewer中打开并且缩放100%时明显模糊。
是否有任何我缺少的设置或为什么会这样?
谢谢, 的Jakub。
可以在此处找到示例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;
答案 0 :(得分:3)
有趣(又烦人)的问题 - 您可能需要查看 Jo0815 到Printing XpsDocument causes resampled images (96dpi?) - FixedDocument prints sharp的冗长答案,引用微软的支持回复 - 一些摘录:
WPF中的某些矢量功能无法在我们的GDI代码中进行模拟 我们求助于将场景的子集转换为GDI位图。这些 位图是缩放模糊的原因。
[...]
这些位图是模糊缩放的原因。问题是 WPF正在以错误的分辨率光栅化为位图。 打印路径旨在将不支持的功能光栅化为 位图,但它应该在设备分辨率下执行。相反 光栅化总是在96dpi完成。这对于屏幕来说很好 但为600dpi打印机产生模糊输出。 [强调我的]
请注意,后者将适用于现在更高的DPI屏幕,当然,我已经遇到过这样的不同时代的模糊 - 你是否偶然使用高DPI显示器?
现在,显然微软并没有完全控制这个设备:
此外,问题仅在打印XPS时发生,而不是 直接打印XAML时出现问题。我很确定有 文档某处说XPS将以设备分辨率打印。 [...] 这是我们的事 计划在下一版本的产品中进行改进,但不是为Win 7。 问题是,当打印XAML时,它将正确呈现 图像在600dpi,但在打印XPS时,它仍然会渲染图像 在96dpi。 由于XAML在打印前转换为XPS似乎 很奇怪,一种打印XPS的方法会产生不同的结果 另一种打印XPS的方法。 [强调我的]
[...]
没有用于配置XPS Document Writer DPI的UI。如果你以后 以与作者不同的DPI打印生成的XPS文档 内部默认您可能会得到位图内容不佳的结果。有了GDI 打印机你可以控制最终的DPI和最终的desitination是 普通纸 - 没有机会重印这份文件。
总之,我仍然会尝试在PrintTicket.PageResolution Property(+1)内调整Néstor Sánchez' approach,如果您的用例确实允许这样做(尽管我远程回忆起在某处阅读,但这没有任何影响); Using the XPS Rasterization Service中的位图分辨率和像素格式部分确认了他遇到的 FixedDocument 问题:
固定页面的XPS光栅化器对象必须知道分辨率 页面将被呈现。 XPSDrv过滤器指定了这一点 分辨率,以每英寸点数(DPI)为输入参数[...]例如,如果显示设备具有分辨率 600 DPI,固定页面描述标准的letter尺寸页面,a 整个页面的位图图像具有以下尺寸[...]
作为潜在的解决方法,您可能希望探索alexandrud针对相关问题How to convert a XPS file to an image in high quality (rather than blurry low resolution)?的解决方案,该问题建议使用xps2img, XPS(XML Paper Specification)文档来设置图像转换实用程序。特别是它允许指定图像大小或DPI ,这可能有所帮助,具体取决于依次应用的打印路径解决方案。
祝你好运!答案 1 :(得分: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