首页 > 解决方案 > 使用带有 PostScript 驱动程序的 GDI+ 的图像质量不佳

问题描述

我正在开发一个程序来使用 C++ 和 Windows GDI+ 在 HDC 上打印不同格式(BMP、JPEG、EMF、...)的图像。使用 MS Publisher Imagesetter 驱动程序,我可以生成 postscript 文件,并通过 GhostScript 函数获得 PDF 文件。如果我尝试打印以下图像:

在此处输入图像描述

我用那些奇怪的方块(原始图像上不存在)获得了以下质量差的结果:

在此处输入图像描述

我用来打印图像的代码部分是:

SetMapMode(hdcPrint,MM_TEXT);
Gdiplus::Graphics graphics(hdcPrint);
graphics.SetPageUnit(Gdiplus::UnitMillimeter);
Gdiplus::Image* image = Gdiplus::Image::FromFile(srPicture->swPathImage); 
graphics.DrawImage(image,x,y,w,h);

我尝试使用许多驱动程序和不同类型的格式(不同于 PostScript:PDF、EMF、真实打印机)打印相同的图像,结果总是可以接受的(不存在正方形)。此外,我尝试使用与 Adob​​e Acrobat Reader DC(Wondershare PDFelement 和 Chrome)不同的 pdf 阅读器打开质量不佳的结果,即使这样,结果也是可以接受的。我还注意到,如果图像包含一些不同的形状(即一条大红线,如下图所示),结果也很好。

在此处输入图像描述

在这一点上,我不知道问题是 Adob​​e 阅读器还是我的实现。使用 GDI+(或纯 GDI)打印不同格式的图像有不同的方法吗?

生成的 PostScript 文件是这个.

标签: c++gdi+msdnpostscript

解决方案


嗯...您没有提供 PostScript 或 PDF 文件,这使得评论变得非常困难。

对我来说,你在什么时候得到你展示的图像并不完全清楚,这是你在 PDF 文件上看到的吗?将 PDF 文件打印到物理打印机时,您会得到什么吗?如果是后者,您如何将 PDF 文件打印到打印机?

您提供的 JPEG 链接非常小(6Kb),您真的要使用该 JPEG 文件吗?

我的猜测(在没有任何文件的情况下,只能猜测)您使用的是旧版本的 Ghostscript。旧版本会解压缩 JPEG 图像,然后使用产生最小结果的任何过滤器重新压缩图像,通常是再次压缩 JPEG。

因为 JPEG 是一种有损格式,所以每次将其应用于图像时,质量都会下降。

较新版本的 Ghostscript 在进入 pdfwrite 设备时不会解压缩 JPEG 图像数据,除非其他选项(例如颜色转换、图像下采样等)需要它。Ghostscript 的当前版本是 9.27,9.28 版本即将发布,我建议您尝试其中之一。

另一种可能性是 PostScript 程序的创建方式是将每个图像样本退化为一个矩形,或者您正在使用也使用该技术的非常旧的 Ghostscript 版本。

请注意,在我看来,这些都不会导致您在此处粘贴的结果,但该版本当然值得研究。发布 PostScript 程序文件(即发送到 Ghostscript 的文件)会更有帮助,因为它至少可以让我缩小问题发生的范围。

[编辑]

该错误似乎是 Acrobat 中的一个有趣的错误。

PostScript 程序使用颜色传递函数来反转 RGB JPEG 图像的颜色样本。(这是一种不受欢迎的做法,它不是传递函数的用途,但并不罕见)。Ghostscript 的 pdfwrite 设备保留了传输功能。

当正确渲染 Ghostscript 时,会产生预期的结果,然而,Acrobat 却惊人地没有,我不知道他们做了什么样的混乱导致你得到的结果,但它显然是错误的。

如果我将 Ghostscript 的 pdfwrite 生产设置更改为应用传输函数而不是保留它们:

-c "<</TransferFunctionInfo /Apply>> setdistillerparams" -f PostScript.ps

然后在 Acrobat 中正确查看生成的文件。如果我修改 Adob​​e Acorbat 的设置,以便它使用 Preserve 而不是 Apply而不是应用)生成的 PDF 文件在 Ghostscript 中正确呈现,并且在 Acrobat 中与 Ghostscript pdfwrite 输出文件相同。

简而言之,恐怕您在这里看到的是一个 Acrobat 渲染错误,您可以通过更改上述 Ghostscript 传输功能设置来解决它,但它在 Ghostscript 中确实不是问题。


推荐阅读