从PDF中提取嵌入的图像

在我开始使用Ubuntu之前,我使用Nitro PDF阅读器来自动从PDF文件中提取图像。在Linux上有没有一个可以做到这一点的PDF阅读器? 我希望能够比拍摄快速/更容易地提取图像。

你能回忆起NitroPDF在矢量图像方面的表现吗?相比之下,pdfimages比NitroPDF做得更好/更差吗? - Léo Léopold Hertz 준영
2可能是从PDF中批量提取图像的命令行工具?的重复问题。 - funky-future
2@funky-future 显然,这两个问题是重复的,但是你的重复目标只有两个答案,而且这两个答案中的一个是垃圾答案,所以应该将重复的方向反转,以免这个问题被重复锤击。 - karel
对于那些偶然发现这个问题并在寻找“如何将PDF转换为一系列图片”的人来说,这与本问题略有不同,但容易混淆,并且相关,请参考我刚刚在这里添加的答案:https://askubuntu.com/a/1187844/327339。 - Gabriel Staples
使用应用程序提取图像不仅更快更容易,而且最重要的是,更精确,因为您可以逐位保留原始图像格式。 - loved.by.Jesus
12个回答

使用pdfimages

pdfimages是一种PDF图像提取工具,它将PDF文件中的图像以PPM、PBM、JPEG或JPEG 2000文件格式保存。

它是poppler-utils软件包的一部分,您需要安装该软件包。

用法:pdfimages [选项] <PDF文件> <图像根目录>

  • 选项-all将以原始格式提取图像。
  • 选项-j将图像提取为.jpg文件(注意:图像将被转换,通常大小比原始图像更大)

示例1:以下代码从PDF文件中提取所有图像,并以它们的原始格式保存。

pdfimages -all in.pdf /tmp/out
示例2:下面的代码从PDF文件中提取所有的图片,并以JPEG格式保存它们。
pdfimages -j in.pdf /tmp/out
将从PDF文件in.pdf中保存图像到文件/tmp/out-000.jpg(或/tmp/out-000.pbm;请参见下文),/tmp/out-001.jpg等。
pdfimages的man page解释如下:
-j:  Normally, all images are written as PBM (for monochrome images) or PPM for
     non-monochrome images) files. With this option,  images in DCT format are
     saved as JPEG files. All non-DCT images are saved in PBM/PPM format as usual.

谢谢。它有效,但我得到的图片是以ppm格式的。我应该如何获得jpeg格式的呢? - 1kb
@1kb - 请检查我的更新答案。 - pl1nk
14希望能有一种能够提取图像原始格式的解决方案会很好。重新编码JPEG并不是真正理想的选择。 - Christian
39@Christian 从man页面中,-all选项将以原生格式写入JPEG、JPEG2000、JBIG2和CCITT图像。CMYK文件将被写入为TIFF文件。所有其他图像将被写入为PNG文件。这相当于指定了选项-png -tiff -j -jp2 -jbig2 -ccitt - William
2请注意,-all开关仅在最新的poppler-utils修订版中受支持。例如,如果您仍在使用12.04版本,您将无法访问此选项。 - Glutanimate
1如果你不能使用-all,可以选择PNM格式。它们是无损的,你可以对图像进行后处理,比如转换为PNG格式。 - Tomasz Gandor
-all开关(以及其他新的图像格式开关)是在poppler版本0.25.0(2013-12-11)中引入的 - 在Ubuntu中,自14.10(Utopic)开始可用。 - pabouk - Ukraine stay strong
当pdfimages无法识别PDF中的图像时,一个可行的替代方法是使用pdftohtml。它会提取图像作为构建的网页的一部分。 - full.stack.ex
1对于相反的情况,将图像转换为PDF,或者更好地将图像包装到PDF中,可以使用img2pdf,链接在这里:https://gitlab.mister-muffin.de/josch/img2pdf(将jpg和jpg2000包装成PDF)。 - erik
@pl1nk pdfimages在处理矢量图像方面表现如何? - Léo Léopold Hertz 준영
3@Christian,使用“$ pdfimages -list <PDF-file>”命令来检查“enc”列中的原始格式,这样您就不必将图像重新编码为另一种格式。 - Jose Barakat
1对我来说,pdfimages提取了大量不是图片的内容(文字、背景、黑色空白图像),而且错过了我正在寻找的图片。 - sdaffa23fdsf
mkdir imgs && pdfimages -j mypdf.pdf imgs/pg生成的是.pbm格式的图像,而不是.jpg格式的图像,并且它们的颜色都是反转的!背景是黑色,文字是白色,而不是白色背景黑色文字!你知道这是怎么回事吗?出错有两个方面:1)当我告诉它输出jpg格式时,它没有输出;2)它的颜色是反转的!pdfimages -v显示版本号为v0.62.0。 - Gabriel Staples
1这里只是给Mac用户添加一个评论。使用brew install poppler命令安装poppler软件包时,将会安装pdfimages命令和其他精彩的poppler软件包组件。 - taiyodayo
请注意,<image-root> 必须是一个绝对路径前缀(在此基础上会添加类似 -001.jpg 的内容以获取文件名)。如果您提供了一个相对的目录名、. 等,它将会静默退出而不执行任何操作。 - Tgr
1如果你运行pdfimages时遇到这个错误,它意味着什么?语法错误:无法获取字段数组<0a> - Gabriel Staples
顺便说一句,我终于给你的回答点了赞,因为我找到了一个很好的使用案例:我用它来验证我是否正确地清理了一个已经打码的PDF文档。我在这里引用了你的回答:Redacting a PDF: draw black boxes over sensitive text or images using LibreOffice Writer or Foxit PDF Reader, then rasterize in Okular - Gabriel Staples

我经常使用Inkscape来做这个。加载页面,然后删除所有其他的东西。优点是你可以得到SVG格式的矢量图像,并按照自己的选择进行修改。

2有些PDF文件只能通过Inkscape内部导入(poppler/cairo导入或pdfimage无法正确解析)。导入后,将图像复制并粘贴到新文件中,并调整页面大小以适应所选内容。 - sdaffa23fdsf
没问题,对我来说那是最好的解决方案,注意你必须一次只选一页! - Jimmy Olano

请注意,这个问题特别询问的是“从PDF中提取嵌入的图像”。关键词是“提取”!这意味着:我有一个PDF文件;它里面有一些图像“嵌入其中”;我该如何将它们提取出来?如果这是你的问题,那么可以使用“pdfimages”作为主要答案由@pl1nk给出。 如何将PDF转换为一堆图像: 许多人在谷歌上搜索并最终找到这个问题(包括我自己),然而,他们实际上在几个小时的沮丧后才意识到自己正在寻找一个稍微不同的问题。所以,如果你正在寻找的是“如何将PDF转换为一堆图像”,而不是“如何从PDF中提取图像”,那么可以使用“pdftoppm”。这里的“PPM”是一种图像格式,所以这只是意味着“PDF转图像”。它的效果非常好,尽管对于现代多核系统来说速度较慢,因为它是单线程应用程序,无法利用多核处理能力。 Ubuntu 18.04带有版本为0.62.0的pdftoppm。使用pdftoppm -v命令检查您的版本:
$ pdftoppm -v
pdftoppm version 0.62.0
Copyright 2005-2017 The Poppler Developers - http://poppler.freedesktop.org
Copyright 1996-2011 Glyph & Cog, LLC

阅读使用 man pdftoppm 命令来查看其众多有用的功能。

支持的输出图像格式:

如 man 页面所示,pdftoppm 允许你使用以下格式输出图像:

  1. PPM(默认)
  2. PNG(使用 -png 参数)
  3. JPEG(使用 -jpeg 参数)
  4. TIFF(使用 -tiff 参数)

它还允许你指定输出为单色图像(-mono 参数)或灰度图像(-gray 参数)(默认是彩色),指定页码,将输出图像放入文件夹中,裁剪和调整大小,指定分辨率,指定 JPEG 质量(介于0和100之间),指定 TIFF 压缩,仅处理偶数或奇数页等。它表现极佳,非常实用!

以下是使用 pdftoppm 将 PDF 转换为一组图像文件的一些示例:

  1. 将ppm文件输出为pg-1.ppmpg-2.ppmpg-3.ppm等,默认分辨率为150 DPI的x和y:

    pdftoppm mypdf.pdf pg
    
  2. 与第一种方式相同,只是将所有输出文件放在名为images的文件夹中:

    mkdir -p images && pdftoppm mypdf.pdf images/pg
    
  3. [我最喜欢的方式] 将图像以jpeg格式输出到名为"images"的文件夹中,分辨率为300 DPI的x和y,而不是默认的150 DPI。请注意,输出的图像采用了某个默认的jpeg压缩级别,每个文件占用大约0.1~1 MB的空间,假设使用标准的8.5" x 11" PDF页面。

    mkdir -p images && pdftoppm -jpeg -r 300 mypdf.pdf images/pg
    
  4. 将图像以jpeg格式输出到名为"images"的文件夹中,分辨率为300 DPI的x和y,并且使用最高质量的jpeg级别!quality值可以从0到100。请参阅man页面。将质量设置为100,分辨率设置为300 DPI时,每个jpeg文件的存储空间预计会是上述方式的两倍,大小范围在~0.2~2MB之间,具体取决于内容,并假设使用8.5" x 11" PDF页面。

    mkdir -p images && pdftoppm -jpeg -jpegopt quality=100 -r 300 mypdf.pdf images/pg
    
  5. 未压缩的.tif*格式输出300 DPI的x和y分辨率的图像。对于300 DPI和8.5" x 11" PDF页面,输出文件的大小约为25 MB。

    mkdir -p images && pdftoppm -tiff -r 300 mypdf.pdf images/pg
    
请注意,将每个页面输出为300 DPI的图像在我的电脑上需要15到45秒的时间。这意味着对于一个有100页的PDF文件来说,以300 DPI jpeg图像输出可能需要长达100 x 45/60 = 75分钟左右。 要计算这个过程在您的电脑上所需的时间,只需在上述任何命令中的pdftoppm部分前加上time命令。例如,这是一个将包含3页的PDF文件转换的输出结果:
$ mkdir -p images && time pdftoppm -tiff -r 300 testpdf.pdf images/pg

real    1m47.572s
user    1m45.675s
sys 0m1.536s
这意味着总实际时钟时间为1分47.572秒,或60 + ~48 = 108秒,即每页108/3 = 36秒。

相关:

1. [如何使用pdf2searchablepdf将PDF转换为可搜索的PDF] 如何将PDF转换为可搜索的文本PDF? 2. 如何将PDF转换为可搜索的文本PDF? 3. 如何将PDF转换为图像? 4. https://stackoverflow.com/questions/6605006/convert-pdf-to-image-with-high-resolution/58795684#58795684 5. https://www.linuxuprising.com/2019/03/how-to-convert-pdf-to-image-png-jpeg.html 6. 如何以编程方式确定PDF文件中图像的DPI?

1这是一个很好的回答,但它回答了一个不同的问题。我建议你找到提出这个问题的人,并将这些信息作为答案发布在那里。 - Alex
这是我一开始想做的,但每次我在谷歌上搜索我要回答的问题时,这个问题总是排在第一位,如果我没记错的话。所以,我觉得不妨就在这里回答它,毕竟谷歌会把人们引导到这里来。也许我应该再次谷歌并将其移动。不过,我不确定是否值得将其移动。 - Gabriel Staples
请看我回答顶部的第二段。那是我当时的推理。 - Gabriel Staples
1当然,我看到了。这并不意味着你不能把它发布在应该发布的地方。 - Alex

你也可以尝试使用pdfmod。它是一个带有图形界面的工具,可以提取图片并进行其他基本的pdf操作。

嗯,对我来说似乎有点问题。插入了一个主要是紫色图像的PDF,结果却变成了绿色的图像。 - DBX12
对我来说,它运行得很好,而且最重要的是,它保留了图像的原始格式,就像 pdfimages -all 一样。 - loved.by.Jesus

我有一个使用LaTeX创建的带有嵌入式图像的双栏PDF文件,其中原始图像是以EPS格式提供的。我尝试了基于pdfimages的解决方案,但不幸的是,它没有返回任何图像。然后我尝试使用Inkscape,但生成的SVG图像失真,并且我也无法将它们导出为EPS格式。 对我来说有效的软件是MasterPdfEditor。 以下是操作步骤:
  • 使用Master PDF Editor打开您的文件
  • 使用编辑工具(Alt+1)选择您需要提取的图像
  • 复制该图像(Ctrl+C)
  • 点击图像周围的虚线框,并查看右侧边栏(对象检查器),然后点击“几何”。在那里,您可以看到所选内容的大小
  • 创建一个新文件(Ctrl+N)。它会提示您提供页面大小。提供您图像的确切大小并创建新文件
  • 现在有点棘手:粘贴图像(Ctrl+V)。图像可能不会显示在新文件中。使用箭头将其移动,直到您能够追踪到它。
  • 使用箭头将图像居中放置在新页面上
  • 保存为PDF

结果质量非常高,但该软件并非免费。有一个演示版本,"允许您尝试所有功能",但会在输出文件上添加水印。坦率地说,我没有注意到生成的PDF中有任何水印。


3这是Ask Ubuntu...我们在这里喜欢开源,而你的解决方案是一个闭源商业解决方案...这怎么比已经得到赞同的答案更好呢?(同时还有-1) - Fabby
4@Fabby 谢谢您的反馈。我不知道这个规定。askubuntu.com上有这样的规则吗?不过,一旦您打开 Ubuntu软件中心,就会得到非免费应用的建议。 - Pantelis Sopasakis
不,没有什么“规定”,这就是为什么我没有投票删除这个回答,但是有更好的免费工具(既免费啤酒又自由言论),所以这只是一个观点。 - Fabby
1+1。我曾经使用过ImageMagick的命令行,但对于寻找图形用户界面的人来说,这是一个有趣的解决方案。 - Ricardo Magalhães Cruz

如果你需要的是PDF/EPS格式的裁剪图像,那么可以使用pdfmod(如To Do所建议的)提取带有图像的页面。 然后使用pdfcrop,通过试错法来正确设置边距进行裁剪:
pdfcrop --margins "-15 -50 0 -140" extracted_page.pdf

使用pdfimages提取的图像可能会分为两个或更多部分。一个简单的方法是将它们导入到LibreOffice Draw中,使用图像裁剪对话框进行裁剪,调整部分的位置,调整页面大小,并以您喜欢的任何格式导出,这样就不用担心提取的格式问题了。

软件使用:Xreader 操作系统:Antergos 步骤: 1. 打开PDF文件。 2. 右键点击图片。 3. 选择“另存为图像”。 4. 输入文件名和扩展名。 5. 保存。

如果你想从PDF中裁剪图像,可以尝试使用Okular。它可以将任何内容(文本或图像)裁剪为PNG或JPEG格式。如果你想从PDF中提取PNG格式的图像,可以使用pdftohtml命令进行简单操作。它将PDF转换为HTML和图像。你可以在这里找到一个示例 - https://www.youtube.com/watch?v=CG1rf7k3xo8。如果你想从PDF中提取多个图像,我建议你尝试这个方法。

LibreOffice Draw -> 右键单击图像 -> 保存

这样做很方便:

  • 对于不熟悉命令行界面的人来说
  • 如果您只想从大型文档中提取一张图片。使用 pdfimages 需要您浏览 1.png、2.png 等文件来找到所需的图片

这种方法有效是因为 LibreOffice Draw 可以处理 PDF,如下所述:如何编辑 PDF?

您可以使用以下命令轻松从命令行界面打开 PDF:

libreoffice doc.pdf

在Ubuntu 22.04上测试过。

enter image description here