为什么在使用 ImageMagick/Ghostscript 时转换此 PDF 文件失败?
Why converting this PDF file fails when using ImageMagick/Ghostscript?
我想转换这个用 LaTeX 编译的 PDF 文件(XeLaTeX 引擎以便使用阿拉伯字体),我想把它上传到网上并防止复制和粘贴它的内容。
因为我正在寻找一个免费软件来完成这项工作,所以我遇到了两个强大的野兽来完成这项工作,即 ImageMagick
和 Ghostscript
。我所需要的只是一次将一个文本 PDF 转换为图像 PDF,如果可能的话最好进行批处理(一次转换多个 PDF)。
我在命令行中 运行 此代码,它适用于英文编写的 PDF:
convert someenglish.pdf output.pdf
现在,当我对阿拉伯语 PDF 执行相同操作时,出现此错误:
convert.exe: PDFDelegateFailed `[ghostscript library] -q -dQUIET -dSAFER -dBATCH
-dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sD
EVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72" "-sOutputFile
=C:/Users/doctorate/AppData/Local/Temp/magick-65203BNMxTDhXtkF%d" "-fC:/Users/doctorate/Ap
pData/Local/Temp/magick-65206AK54hOoKA62" "-fC:/Users/doctorate/AppData/Local/Temp/ma
gick-6520hDn-KMyTyxy2"': **** Error reading a content stream. The page may be
incomplete.
**** Incorrect object count in object stream.
Error: /rangecheck in resolveobjectstream
Operand stack:
78424 10 1 10 --dict:7/15(L)-- 26 --nostringval-- 35 --nostri
ngval-- --dict:2/2(L)-- --dict:2/2(L)-- --dict:2/2(L)-- --dict:2/2(L)--
--dict:4/4(L)-- --dict:4/4(L)-- --dict:4/4(L)-- --dict:4/4(L)-- --dict
:4/4(L)-- --dict:3/3(L)-- --dict:2/2(L)-- --nostringval-- --dict:7/7(L)-
- --dict:10/10(L)-- --nostringval-- --nostringval-- Type Font Subtyp
e CIDFontType2 BaseFont MYCROL+(AH
Execution stack:
%interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-
- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- fa
lse 1 %stopped_push 1983 1 3 %oparray_pop 1982 1 3 %oparray_
pop 1966 1 3 %oparray_pop --nostringval-- --nostringval-- --nostri
ngval-- --nostringval-- --nostringval-- --nostringval-- --nostringval--
--nostringval-- --nostringval--
Dictionary stack:
--dict:1193/1684(ro)(G)-- --dict:1/20(G)-- --dict:82/200(L)-- --dict:82
/200(L)-- --dict:116/127(ro)(G)-- --dict:280/300(ro)(G)-- --dict:24/32(L)-
-
Current allocation mode is local
GPL Ghostscript 9.15: Unrecoverable error, exit code 1
@ error/pdf.c/InvokePDFDelegate/263.
convert.exe: no images defined `test.pdf' @ error/convert.c/ConvertImageCommand/
3210.
问题
我在这里错过了什么?我不是程序员,所以请在您的回答中考虑这一点。如果您能展示如何在批处理过程中执行此操作,我将不胜感激。
注释
Windows 7 32bit
Ghostscript 版本 9.15
图像质量对我来说不是问题,即使 72dpi 也可以
我想在输出的大小和文本的清晰度之间取得平衡。我只希望文本在网络上可读,而不是对其进行一些 OCR 处理,因此图像不需要非常清晰。输出的大小更重要,越少越好,老实说,我不知道什么可能更好;在这种情况下,将 PDF 文件转换为 PNG 或 JPEG。
我不想将一个 PDF 拆分为多个连续命名的 PNG 或 JPEG,只是将一个 PDF 转换为另一个 PDF,但作为内部图像,不再需要复制和粘贴文本。
更新
我试图制作一个最小的工作示例 PDF 来模仿原始 PDF,发现问题是通过包含一种名为 (AH) Manal Black
的特定阿拉伯字体出现的。 运行 pdffonts
来自此 MWE PDF 的命令行给出:
Syntax Error (18062): Illegal character ')'
Syntax Error (18076): Dictionary key must be a name object
Syntax Error (18085): Dictionary key must be a name object
Syntax Error (18248): Illegal character ')'
Syntax Error (18248): Dictionary key must be a name object
Syntax Error (18253): Dictionary key must be a name object
Syntax Error (18599): Illegal character ')'
Syntax Error (18599): Dictionary key must be a name object
Syntax Error (18607): Dictionary key must be a name object
name type emb sub uni object ID
------------------------------------ ----------------- --- --- --- ---------
GAKHDJ+(AH CID TrueType yes yes yes 5 0
HTCSVQ+Amiri-Regular CID TrueType yes yes yes 7 0
通过在使用 LaTeX/XeTeX 引擎编译文档时排除这种阿拉伯字体,转换命令可以像在其他英文 PDF 中一样正常工作。所以这个问题很可能与字体解析有关。
更新: 这里是一个最低限度的工作示例:https://www.dropbox.com/s/qdeuzips0ivas4q/mwe_ar.pdf?dl=0
最小工作示例具有 PDF 对象编号。 10 作为 ObjStm
(对象流),可以在其中找到这部分(我编辑了空白格式以提高可读性):
<< /Type /Font
/Subtype /Type0
/BaseFont /GAKHDJ+#28AH)#20Manal#20Black
/Encoding /Identity-H
/DescendantFonts [4 0 R]
/ToUnicode 12 0 R
>>
所以字体名称 (AH) Manal Black
已将空格正确地十六进制转义为 #20
并将左括号 (
正确转义为 #28
,但它没有十六进制将右括号 )
转义为 #29
,这是应该的。
在不了解 PDF 生成过程的更多信息的情况下,我猜 Creator/Producer
组合通过文件的元数据给出,
Creator: XeTeX output 2015.05.01:1207
Producer: xdvipdfmx (20140317)
是要受到指责的。这是PDF生成软件的一个bug...
更新
也许我应该透露一下我是如何剖析和解压缩 MWE PDF 的:
用 QPDF 试了一下没用:
qpdf --qdf --object-streams=disable mwe_ar.pdf qdf.pdf
object stream 10 (file position 585): unexpected )
用 pdftk
尝试也没有用:
pdftk mwe_ar.pdf cat pdftk.pdf uncompress
Error: Unable to find file.
Error: Failed to open PDF file:
mwe_ar.pdf
Errors encountered. No output created.
Done. Input errors, so no output created.
尝试使用 MuPDF 的 mutool
也失败了:
mutool clean -d mwe_ar.pdf mutool.pdf
warning: lexical error (unexpected ')')
error: invalid key in dict
error: cannot parse dict
error: cannot open object stream (10 0 R)
error: cannot load object stream containing object (1 0 R)
warning: cannot load object (1 0 R) into cache
warning: lexical error (unexpected ')')
error: invalid key in dict
error: cannot parse dict
error: cannot open object stream (10 0 R)
error: cannot load object stream containing object (4 0 R)
error: cannot load object (4 0 R) into cache
最后,不得已,PeePDF.py救场:
$ cat peepdf-commands.txt
object 10
$ peepdf.py -s peepdf-commands.txt
<< /Length 1000
/N 13
/Type /ObjStm
/Filter /FlateDecode
/First 84 >>
stream
9 0 3 72 11 133 2 197 1 312 15 343 4 446 14 625 19 876 6 1344 18 1514 5 1758 7 1886 <</Font<</F1 5 0 R/F2 7 0 R>>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>>
<</Resources 9 0 R/Type/Page/Parent 11 0 R/Contents[8 0 R]>>
<</Type/Pages/Count 1/Kids[3 0 R]/MediaBox[0 0 595.28 841.89]>>
<</Creator( XeTeX output 2015.05.01:1207)/Producer(xdvipdfmx \(20140317\))/CreationDate(D:20150501120749+01'00')>>
<</Pages 11 0 R/Type/Catalog>>
[417[251]421[257]424[368]443[470]445[355]450[380]480[322]498[480 233]505[461]508[256]514[326]520[264]]
<</Type/Font/Subtype/CIDFontType2/BaseFont/GAKHDJ+#28AH)#20Manal#20Black/FontDescriptor 14 0 R/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/DW 199/W 15 0 R>>
<</Type/FontDescriptor/Ascent 529/Descent -415/StemV 109/CapHeight 529/AvgWidth 392/FontBBox[-112 -321 1006 1137]/ItalicAngle 0/Flags 6/Style<</Panose<000000000000000000000000>>>/FontName/GAKHDJ+#28AH)#20Manal#20Black/FontFile2 16 0 R/CIDSet 17 0 R>>
[39[693]41[522]51[535]108[415]124[415]388[218 926]402[1213]406[541]446[586]1886[317]1992[229]2016[366]2021[366]2105[244]2108[244]2139[1006]2150[295]2162[378]2227[379 452]2272[589]2294[176]2300[198]2308[389]2339[343]2356[723]2359[1079]2397[552]2413[346]2457[177]2491[299]2912[349]2952[219]2969[209]2973[148]2976[302]2981[341]3027[168]3149[550]3297[259]3325[292]3726[248]3732[319]3853[411]3893[179]4021[55]4323[104]4627[560]5068[238]5106[476]5322[159]5328[222]6366[93]]
<</Type/Font/Subtype/CIDFontType2/BaseFont/HTCSVQ+Amiri-Regular/FontDescriptor 18 0 R/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/DW 190/W 19 0 R>>
<</Type/FontDescriptor/Ascent 1123/Descent -635/StemV 87/CapHeight 1123/AvgWidth 685/FontBBox[-581 -900 11467 1815]/ItalicAngle 0/Flags 6/Style<</Panose<000000000500000000000000>>>/FontName/HTCSVQ+Amiri-Regular/FontFile2 20 0 R/CIDSet 21 0 R>>
<</Type/Font/Subtype/Type0/BaseFont/GAKHDJ+#28AH)#20Manal#20Black/Encoding/Identity-H/DescendantFonts[4 0 R]/ToUnicode 12 0 R>>
<</Type/Font/Subtype/Type0/BaseFont/HTCSVQ+Amiri-Regular/Encoding/Identity-H/DescendantFonts[6 0 R]/ToUnicode 13 0 R>>
endstream
我使用 PeePDF.py 的次数越多,我就越喜欢它。谢谢 Jose Miguel 提供的这个好工具!
我通常使用 pdftocairo 来解决这个问题:
pdftocairo corruptedinfile.pdf -pdf outfile.pdf
之后ghostscript可以正常处理
我想转换这个用 LaTeX 编译的 PDF 文件(XeLaTeX 引擎以便使用阿拉伯字体),我想把它上传到网上并防止复制和粘贴它的内容。
因为我正在寻找一个免费软件来完成这项工作,所以我遇到了两个强大的野兽来完成这项工作,即 ImageMagick
和 Ghostscript
。我所需要的只是一次将一个文本 PDF 转换为图像 PDF,如果可能的话最好进行批处理(一次转换多个 PDF)。
我在命令行中 运行 此代码,它适用于英文编写的 PDF:
convert someenglish.pdf output.pdf
现在,当我对阿拉伯语 PDF 执行相同操作时,出现此错误:
convert.exe: PDFDelegateFailed `[ghostscript library] -q -dQUIET -dSAFER -dBATCH
-dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sD
EVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72" "-sOutputFile
=C:/Users/doctorate/AppData/Local/Temp/magick-65203BNMxTDhXtkF%d" "-fC:/Users/doctorate/Ap
pData/Local/Temp/magick-65206AK54hOoKA62" "-fC:/Users/doctorate/AppData/Local/Temp/ma
gick-6520hDn-KMyTyxy2"': **** Error reading a content stream. The page may be
incomplete.
**** Incorrect object count in object stream.
Error: /rangecheck in resolveobjectstream
Operand stack:
78424 10 1 10 --dict:7/15(L)-- 26 --nostringval-- 35 --nostri
ngval-- --dict:2/2(L)-- --dict:2/2(L)-- --dict:2/2(L)-- --dict:2/2(L)--
--dict:4/4(L)-- --dict:4/4(L)-- --dict:4/4(L)-- --dict:4/4(L)-- --dict
:4/4(L)-- --dict:3/3(L)-- --dict:2/2(L)-- --nostringval-- --dict:7/7(L)-
- --dict:10/10(L)-- --nostringval-- --nostringval-- Type Font Subtyp
e CIDFontType2 BaseFont MYCROL+(AH
Execution stack:
%interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-
- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- fa
lse 1 %stopped_push 1983 1 3 %oparray_pop 1982 1 3 %oparray_
pop 1966 1 3 %oparray_pop --nostringval-- --nostringval-- --nostri
ngval-- --nostringval-- --nostringval-- --nostringval-- --nostringval--
--nostringval-- --nostringval--
Dictionary stack:
--dict:1193/1684(ro)(G)-- --dict:1/20(G)-- --dict:82/200(L)-- --dict:82
/200(L)-- --dict:116/127(ro)(G)-- --dict:280/300(ro)(G)-- --dict:24/32(L)-
-
Current allocation mode is local
GPL Ghostscript 9.15: Unrecoverable error, exit code 1
@ error/pdf.c/InvokePDFDelegate/263.
convert.exe: no images defined `test.pdf' @ error/convert.c/ConvertImageCommand/
3210.
问题
我在这里错过了什么?我不是程序员,所以请在您的回答中考虑这一点。如果您能展示如何在批处理过程中执行此操作,我将不胜感激。
注释
Windows 7 32bit
Ghostscript 版本 9.15
图像质量对我来说不是问题,即使 72dpi 也可以
我想在输出的大小和文本的清晰度之间取得平衡。我只希望文本在网络上可读,而不是对其进行一些 OCR 处理,因此图像不需要非常清晰。输出的大小更重要,越少越好,老实说,我不知道什么可能更好;在这种情况下,将 PDF 文件转换为 PNG 或 JPEG。
我不想将一个 PDF 拆分为多个连续命名的 PNG 或 JPEG,只是将一个 PDF 转换为另一个 PDF,但作为内部图像,不再需要复制和粘贴文本。
更新
我试图制作一个最小的工作示例 PDF 来模仿原始 PDF,发现问题是通过包含一种名为 (AH) Manal Black
的特定阿拉伯字体出现的。 运行 pdffonts
来自此 MWE PDF 的命令行给出:
Syntax Error (18062): Illegal character ')'
Syntax Error (18076): Dictionary key must be a name object
Syntax Error (18085): Dictionary key must be a name object
Syntax Error (18248): Illegal character ')'
Syntax Error (18248): Dictionary key must be a name object
Syntax Error (18253): Dictionary key must be a name object
Syntax Error (18599): Illegal character ')'
Syntax Error (18599): Dictionary key must be a name object
Syntax Error (18607): Dictionary key must be a name object
name type emb sub uni object ID
------------------------------------ ----------------- --- --- --- ---------
GAKHDJ+(AH CID TrueType yes yes yes 5 0
HTCSVQ+Amiri-Regular CID TrueType yes yes yes 7 0
通过在使用 LaTeX/XeTeX 引擎编译文档时排除这种阿拉伯字体,转换命令可以像在其他英文 PDF 中一样正常工作。所以这个问题很可能与字体解析有关。
更新: 这里是一个最低限度的工作示例:https://www.dropbox.com/s/qdeuzips0ivas4q/mwe_ar.pdf?dl=0
最小工作示例具有 PDF 对象编号。 10 作为 ObjStm
(对象流),可以在其中找到这部分(我编辑了空白格式以提高可读性):
<< /Type /Font
/Subtype /Type0
/BaseFont /GAKHDJ+#28AH)#20Manal#20Black
/Encoding /Identity-H
/DescendantFonts [4 0 R]
/ToUnicode 12 0 R
>>
所以字体名称 (AH) Manal Black
已将空格正确地十六进制转义为 #20
并将左括号 (
正确转义为 #28
,但它没有十六进制将右括号 )
转义为 #29
,这是应该的。
在不了解 PDF 生成过程的更多信息的情况下,我猜 Creator/Producer
组合通过文件的元数据给出,
Creator: XeTeX output 2015.05.01:1207
Producer: xdvipdfmx (20140317)
是要受到指责的。这是PDF生成软件的一个bug...
更新
也许我应该透露一下我是如何剖析和解压缩 MWE PDF 的:
用 QPDF 试了一下没用:
qpdf --qdf --object-streams=disable mwe_ar.pdf qdf.pdf object stream 10 (file position 585): unexpected )
用
pdftk
尝试也没有用:pdftk mwe_ar.pdf cat pdftk.pdf uncompress Error: Unable to find file. Error: Failed to open PDF file: mwe_ar.pdf Errors encountered. No output created. Done. Input errors, so no output created.
尝试使用 MuPDF 的
mutool
也失败了:mutool clean -d mwe_ar.pdf mutool.pdf warning: lexical error (unexpected ')') error: invalid key in dict error: cannot parse dict error: cannot open object stream (10 0 R) error: cannot load object stream containing object (1 0 R) warning: cannot load object (1 0 R) into cache warning: lexical error (unexpected ')') error: invalid key in dict error: cannot parse dict error: cannot open object stream (10 0 R) error: cannot load object stream containing object (4 0 R) error: cannot load object (4 0 R) into cache
最后,不得已,PeePDF.py救场:
$ cat peepdf-commands.txt object 10 $ peepdf.py -s peepdf-commands.txt << /Length 1000 /N 13 /Type /ObjStm /Filter /FlateDecode /First 84 >> stream 9 0 3 72 11 133 2 197 1 312 15 343 4 446 14 625 19 876 6 1344 18 1514 5 1758 7 1886 <</Font<</F1 5 0 R/F2 7 0 R>>/ProcSet[/PDF/Text/ImageC/ImageB/ImageI]>> <</Resources 9 0 R/Type/Page/Parent 11 0 R/Contents[8 0 R]>> <</Type/Pages/Count 1/Kids[3 0 R]/MediaBox[0 0 595.28 841.89]>> <</Creator( XeTeX output 2015.05.01:1207)/Producer(xdvipdfmx \(20140317\))/CreationDate(D:20150501120749+01'00')>> <</Pages 11 0 R/Type/Catalog>> [417[251]421[257]424[368]443[470]445[355]450[380]480[322]498[480 233]505[461]508[256]514[326]520[264]] <</Type/Font/Subtype/CIDFontType2/BaseFont/GAKHDJ+#28AH)#20Manal#20Black/FontDescriptor 14 0 R/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/DW 199/W 15 0 R>> <</Type/FontDescriptor/Ascent 529/Descent -415/StemV 109/CapHeight 529/AvgWidth 392/FontBBox[-112 -321 1006 1137]/ItalicAngle 0/Flags 6/Style<</Panose<000000000000000000000000>>>/FontName/GAKHDJ+#28AH)#20Manal#20Black/FontFile2 16 0 R/CIDSet 17 0 R>> [39[693]41[522]51[535]108[415]124[415]388[218 926]402[1213]406[541]446[586]1886[317]1992[229]2016[366]2021[366]2105[244]2108[244]2139[1006]2150[295]2162[378]2227[379 452]2272[589]2294[176]2300[198]2308[389]2339[343]2356[723]2359[1079]2397[552]2413[346]2457[177]2491[299]2912[349]2952[219]2969[209]2973[148]2976[302]2981[341]3027[168]3149[550]3297[259]3325[292]3726[248]3732[319]3853[411]3893[179]4021[55]4323[104]4627[560]5068[238]5106[476]5322[159]5328[222]6366[93]] <</Type/Font/Subtype/CIDFontType2/BaseFont/HTCSVQ+Amiri-Regular/FontDescriptor 18 0 R/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/DW 190/W 19 0 R>> <</Type/FontDescriptor/Ascent 1123/Descent -635/StemV 87/CapHeight 1123/AvgWidth 685/FontBBox[-581 -900 11467 1815]/ItalicAngle 0/Flags 6/Style<</Panose<000000000500000000000000>>>/FontName/HTCSVQ+Amiri-Regular/FontFile2 20 0 R/CIDSet 21 0 R>> <</Type/Font/Subtype/Type0/BaseFont/GAKHDJ+#28AH)#20Manal#20Black/Encoding/Identity-H/DescendantFonts[4 0 R]/ToUnicode 12 0 R>> <</Type/Font/Subtype/Type0/BaseFont/HTCSVQ+Amiri-Regular/Encoding/Identity-H/DescendantFonts[6 0 R]/ToUnicode 13 0 R>> endstream
我使用 PeePDF.py 的次数越多,我就越喜欢它。谢谢 Jose Miguel 提供的这个好工具!
我通常使用 pdftocairo 来解决这个问题:
pdftocairo corruptedinfile.pdf -pdf outfile.pdf
之后ghostscript可以正常处理