python - 为什么使用 PIL 保存为 pdf 会在字体周围产生灰色区域

标签 python pdf png python-imaging-library

我想将 pdf 文件转换为 png 以便在 Python 中进行操作,并将其另存为 pdf,但在此过程中,字体周围会创建一个灰色区域(我的图像是一个简单的黑白打字文档) 。它非常微弱,在屏幕上有点难以看到,但打印后就变得相当明显。

这是我使用的具体命令: PDF 到 PNG(灰度、 super 采样以保持图像质量):

convert -density 500 -alpha off file_in.pdf -scale 1700x2200 -bordercolor black -border 1x1 -fuzz 20% -trim +repage -colorspace Gray -depth 4 file_out.png

在 Python 中

import Image 
img = Image.open('file_out.png')
img.save('file_out2.pdf')

我还尝试使用 Ghostscript 将 pdf 转换为 png:

gs -sDEVICE=png16m -sOutputFile=file.png -dNOPAUSE -dBATCH -r300 file_out.pdf 

保存结果。

这是部分内容

identify -verbose file.png

给出 ImageMagick png :

 Format: PNG (Portable Network Graphics)
  Class: PseudoClass
  Geometry: 1700x2200+0+0
  Resolution: 500x500
  Print size: 3.4x4.4
  Units: Undefined
  Type: Grayscale
  Base type: Grayscale
  Endianess: Undefined
  Colorspace: Gray
  Depth: 8/4-bit
  Channel depth:
    gray: 4-bit

有人有解决办法吗?或者至少有一个解释?

编辑: 我发现使用“-sample 1700x2200”而不是“-scale 1700x2200”修复了字体周围的灰色,但随后细线几乎消失并且字体出现锯齿现象...

最佳答案

pdf 格式基本上是一种矢量格式,还可以包含位图(“光栅”)图像。

如果原始 pdf 包含扫描文档,它通常只包含位图图像(通常采用 tiffjpeg 格式),并且然后将其转换为 png 就可以了(如果您坚持图像的原始分辨率)。

但是,如果原始文件包含矢量图形(包括文本字符串),则将其转换为位图通常会引入采样错误。为了避免这些问题,您可以使用 1 位颜色深度(“黑白”格式)和至少与打印机匹配的分辨率。不过,这将产生一个相当大的 png 文件。使用 tiff 格式可能会生成较小的文件。扫描大型绘图时经常会看到“tiff-inside-pdf”格式。根据 ImageMagick 的 identify 程序,这样的 tiff 文件看起来像这样:

  Format: TIFF (Tagged Image File Format)
  Class: DirectClass
  Geometry: 13231x9355+0+0
  Resolution: 400x400
  Print size: 33.0775x23.3875
  Units: PixelsPerInch
  Type: Bilevel
  Base type: Bilevel
  Endianess: MSB
  Colorspace: Gray
  Depth: 1-bit
  Channel depth:
    gray: 1-bit

尽管 tiff 文件很大,但它只有 144 kb。 tiff2pdf 程序(tiff 包的一部分)可以将这些文件转换为漂亮且小的 pdf 文件。

但保留文档格式的最佳方法是编辑 pdf 文件本身,而不是将其转换为其他格式。

有一个用于操作pdf文档的Python模块; PyPDF2 。但是,由于您没有指定您想要对文档执行什么操作,因此无法判断这是否可以执行您想要的操作。还有ReportLab ,但这更多的是生成 pdf 文件。如果您的系统上安装了 cairo 库,pycairo是生成 pdf 文档的较轻量级选项。

通常用于操作 pdf 文件的优秀实用程序是 pdftk (用java编写)。

编辑:灰度采样总是会引入采样伪影。这些本身并不是错误,只是采样过程的结果。

按照 Ben Jackson 的说法,可以将 pdf 文件反编译为 PostScript。有几个实用程序可以帮助您做到这一点; pdftops 来自poppler -utils 包,以及 ghostscript 附带的 pdf2ps 。根据我的经验,pdftops 往往会产生更好的可用输出。

但我还没有找到一个好的方法来自动化这个过程。以下是使用 pdftops 反编译的 Numpy 用户指南片段:

(At)
[7.192997
0
2.769603
0] Tj
-314 TJm
(the)
[2.769603
0
4.9813
0
4.423394
0] Tj
-313 TJm
(core)
[4.423394
0
4.9813
0
3.317546
0
4.423394
0] Tj
-314 TJm
(of)
[4.9813
0
3.317546
0] Tj
-313 TJm
(the)
[2.769603
0
4.9813
0
4.423394
0] Tj
-314 TJm
(NumPy)
[7.192997
0
4.9813
0
7.750903
0
5.539206
0
4.9813
0] Tj
-314 TJm
(package,)
[4.9813
0
4.423394
0
4.423394
0
4.9813
0
4.423394
0
4.9813
0
4.423394
0
2.49065
0] Tj
-329 TJm

这会产生句子“At the core of the Numpy package”,因此,如果您在 PostScript 文件中查找 () 之间的任何内容,您将获得字符串。

因此更改单个单词或删除短片段并不难;

  • 在反编译的 PostScript 中找到正确的单词。
  • 编辑它们(以及周围的参数!)
  • 重新编译为 pdf(使用 Ghostscript)。

但是您必须查看文档的开头并查看函数 TjTJm 的作用。如果要替换文本,则必须删除它们并使用 TjTJm 的正确参数放入新文本和代码。这需要了解 PostScript。而且如果你要替换一个句子,你通常不能用更长的句子来替换它;空间不够...

因此,通常建议尝试让原始应用程序更改输出。

关于python - 为什么使用 PIL 保存为 pdf 会在字体周围产生灰色区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15714707/

相关文章:

安卓png优化

python - 使用 AMPPS 在 Mac OS 上的 PyCharm 中安装 Msyqldb 或 Flask-mysqldb(或任何 mysql 客户端)时出现错误 "-fabi-version=2"

Python - 如何在检查前向元素时循环遍历列表?

php - TCPDF 在末尾添加了一个额外的空白页

python - PyPDF2 不会从 PDF 中提取所有文本

php - PHP 中的 SVG 到 PNG 结果错误

python - 如何将多个不同语言的 CSV 文件合并到一个 CSV 文件中?

python - 使用 eclipse 和 python/django 进行开发时个人/家庭使用的最佳版本控制系统

pdf - 链接到 LaTeX Beamer 中的外部应用程序

asp.net - 将 PNG 保存到 Response.OutputStream 时的行为不一致