我想将 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
包含扫描文档,它通常只包含位图图像(通常采用 tiff
或 jpeg
格式),并且然后将其转换为 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)。
但是您必须查看文档的开头并查看函数 Tj
和 TJm
的作用。如果要替换文本,则必须删除它们并使用 Tj
和 TJm
的正确参数放入新文本和代码。这需要了解 PostScript。而且如果你要替换一个句子,你通常不能用更长的句子来替换它;空间不够...
因此,通常建议尝试让原始应用程序更改输出。
关于python - 为什么使用 PIL 保存为 pdf 会在字体周围产生灰色区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15714707/