从pdf提取页面作为jpeg


95

在python代码中,如何有效地将pdf中的某个页面另存为jpeg文件?(用例:我有一个python flask网络服务器,将在其中上传pdf-s,并存储与每个页面相对应的jpeg-s。)

该解决方案已经结束,但是问题在于它不会将整个页面转换为jpeg。


1
根据图像,最好提取为png。如果页面主要包含文本,则适用此规则。
保罗·鲁尼

Answers:


125

可以使用pdf2image库。

您可以使用以下方法简单地安装它:

pip install pdf2image

安装后,您可以使用以下代码获取图像。

from pdf2image import convert_from_path
pages = convert_from_path('pdf_file', 500)

以jpeg格式保存页面

for page in pages:
    page.save('out.jpg', 'JPEG')

编辑:Github repo pdf2image也提到它使用pdftoppm并且需要其他安装:

pdftoppm是执行实际操作的软件。它作为更大的软件包poppler的一部分分发。Windows用户必须为Windows安装poppler。Mac用户必须为Mac安装poppler。如果发行版未安装,则Linux用户将预先安装pdftoppm(已在Ubuntu和Archlinux上进行了测试),请运行sudo apt install poppler-utils

您可以通过以下步骤使用anaconda在Windows下安装最新版本:

conda install -c conda-forge poppler

注意:http://blog.alivate.com.au/poppler-windows/上提供的Windows版本最高为0.67,但请注意,0.68已于2018年8月发布,因此您将无法获得最新功能或错误修复。


4
嗨,poppler只是一个压缩文件,没有安装任何东西,该怎么处理dll或bin文件?
gaurwraith

@gaurwraith:使用以下链接到poppler。由于某些原因,Rodrigo的描述中的链接与github存储库中的链接不同。
Tobias '18

@Keval Dave您是否已在Windows计算机上安装poppler并尝试了pdf2image?请使用哪个Windows?
SKR

1
@elPastor您可以在conver_from_path功能的参数添加first_page和last_page到指定的页面只转换
Keval戴夫

1
@Jacob 500是dpi。权衡所需的分辨率和可用的计算。在我的实验中,大多数情况下,500个效果很好,而300个让我获得了低分辨率的图像。
Keval Dave

36

我发现这个简单的解决方案PyMuPDF可以输出到png文件。请注意,该库被导入为“ fitz”,这是它使用的渲染引擎的历史名称。

import fitz

pdffile = "infile.pdf"
doc = fitz.open(pdffile)
page = doc.loadPage(0)  # number of page
pix = page.getPixmap()
output = "outfile.png"
pix.writePNG(output)

1
请在回答中添加解释。
Shanteshwar Inde

1
一个好的库,它可以毫无问题地安装在Windows 10上(不需要轮子)。github.com/pymupdf
Che同志

7
这是最好的答案。这是唯一不需要在我的操作系统上进行额外安装的代码。Python脚本应专注于在Python系统中工作。我不需要安装poppler,pdftoppm,imageMagick或ghostscript等(Python 3.6)
ZStoneDPM

1
实际上,它需要另一个安装(fitz库,甚至没有被引用就导入了它及其依赖项),这个答案是不完整的(就像这个问题的所有答案一样)
Tommaso Guerrini

1
@JJPty我们可以从pdfurl中获取代替路径中的pdf文件吗?另外,png文件是否可能是流内数据而不是output-png文件?
Shubham Agrawal

18

Python库pdf2image其实(在对方的回答中)没有做远不止推出 pdttoppmsubprocess.Popen,所以这里是一个短版,直接做:

PDFTOPPMPATH = r"D:\Documents\software\____PORTABLE\poppler-0.51\bin\pdftoppm.exe"
PDFFILE = "SKM_28718052212190.pdf"

import subprocess
subprocess.Popen('"%s" -png "%s" out' % (PDFTOPPMPATH, PDFFILE))

这是Windows安装链接pdftoppm(包含在名为poppler的软件包中):http : //blog.alivate.com.au/poppler-windows/


4
嗨,pdftoppm的Windows安装链接只是一堆压缩文件,为了使其正常工作,您与它们有什么关系?谢谢!
gaurwraith

14

无需在操作系统上安装Poppler。这将起作用:

点安装魔杖

from wand.image import Image

f = "somefile.pdf"
with(Image(filename=f, resolution=120)) as source: 
    for i, image in enumerate(source.sequence):
        newfilename = f[:-4] + str(i + 1) + '.jpeg'
        Image(image).save(filename=newfilename)

10
需要安装ImageMagick库才能在魔杖上工作。
Neeraj Gulia

2
我尝试了此操作,还需要安装Ghostscript(使用Windows 10和Python 3.7)。做到了,它运行完美。
jcf

1
f [:-4]的作用是什么?它在其他任何地方均未提及
Ari

@Ari f [:-4]将从文件名中切出“ .pdf”(字符串切片),以使用其他扩展名创建新文件名。
Fabian

9

@gaurwraith,为Windows安装poppler并使用pdftoppm.exe,如下所示:

  1. http://blog.alivate.com.au/poppler-windows/下载带有Poppler最新二进制文件/ dll的zip文件,然后解压缩到程序文件文件夹中的新文件夹。例如:“ C:\ Program Files(x86)\ Poppler”。

  2. 将“ C:\ Program Files(x86)\ Poppler \ poppler-0.68.0 \ bin”添加到您的SYSTEM PATH环境变量。

  3. 从cmd行安装pdf2image模块->“ pip install pdf2image”。

  4. 或者,如用户Basj所述,使用Python的子进程模块直接从代码中执行pdftoppm.exe。

@vishvAs vAsuki,此代码应通过子处理模块为给定文件夹中一个或多个pdf的所有页面生成所需的jpg:

import os, subprocess

pdf_dir = r"C:\yourPDFfolder"
os.chdir(pdf_dir)

pdftoppm_path = r"C:\Program Files (x86)\Poppler\poppler-0.68.0\bin\pdftoppm.exe"

for pdf_file in os.listdir(pdf_dir):

    if pdf_file.endswith(".pdf"):

        subprocess.Popen('"%s" -jpeg %s out' % (pdftoppm_path, pdf_file))

或使用pdf2image模块:

import os
from pdf2image import convert_from_path

pdf_dir = r"C:\yourPDFfolder"
os.chdir(pdf_dir)

    for pdf_file in os.listdir(pdf_dir):

        if pdf_file.endswith(".pdf"):

            pages = convert_from_path(pdf_file, 300)
            pdf_file = pdf_file[:-4]

            for page in pages:

               page.save("%s-page%d.jpg" % (pdf_file,pages.index(page)), "JPEG")

这很有帮助。谢谢!
Sreekiran

1
这实际上应该是公认的答案。显示如何处理Poppler已安装的二进制文件
Kunj Mehta,

3

他们是一个名为pdftojpg的实用程序,可用于将pdf转换为img

您可以在这里找到代码https://github.com/pankajr141/pdf2jpg

from pdf2jpg import pdf2jpg
inputpath = r"D:\inputdir\pdf1.pdf"
outputpath = r"D:\outputdir"
# To convert single page
result = pdf2jpg.convert_pdf2jpg(inputpath, outputpath, pages="1")
print(result)

# To convert multiple pages
result = pdf2jpg.convert_pdf2jpg(inputpath, outputpath, pages="1,0,3")
print(result)

# to convert all pages
result = pdf2jpg.convert_pdf2jpg(inputpath, outputpath, pages="ALL")
print(result)

2
这个Java东西只是删除了我整个充满pdf操作python脚本的文件夹....?
Ulf Gjerdingen '18

2

对于基于Linux的系统,GhostScript的执行速度比Poppler快得多。

以下是pdf到图像转换的代码。

def get_image_page(pdf_file, out_file, page_num):
    page = str(page_num + 1)
    command = ["gs", "-q", "-dNOPAUSE", "-dBATCH", "-sDEVICE=png16m", "-r" + str(RESOLUTION), "-dPDFFitPage",
               "-sOutputFile=" + out_file, "-dFirstPage=" + page, "-dLastPage=" + page,
               pdf_file]
    f_null = open(os.devnull, 'w')
    subprocess.call(command, stdout=f_null, stderr=subprocess.STDOUT)

GhostScript可以使用以下命令安装在macOS上 brew install ghostscript

其他平台的安装信息可在此处找到。如果您的系统上尚未安装它。


0

我使用pdf2image的(也许)简单得多的选项:

cd $dir
for f in *.pdf
do
  if [ -f "${f}" ]; then
    n=$(echo "$f" | cut -f1 -d'.')
    pdftoppm -scale-to 1440 -png $f $conv/$n
    rm $f
    mv  $conv/*.png $dir
  fi
done

这是循环中bash脚本的一小部分,用于使用狭窄的投射设备。每5秒钟检查一次添加的pdf文件(全部)并进行处理。这是针对演示设备的,最终转换将在远程服务器上完成。现在可以转换为.PNG,但是.JPG也可以。

这种转换以及A4格式的过渡,显示视频,两个平滑滚动文本和徽标(三个版本中有过渡),将Pi3设置为最高4x 100%cpu-load ;-)


0
from pdf2image import convert_from_path
import glob

pdf_dir = glob.glob(r'G:\personal\pdf\*')  #your pdf folder path
img_dir = "G:\\personal\\img\\"           #your dest img path

for pdf_ in pdf_dir:
    pages = convert_from_path(pdf_, 500)
    for page in pages:
        page.save(img_dir+pdf_.split("\\")[-1][:-3]+"jpg", 'JPEG')

如果您解释了所提供的代码如何回答该问题,那么这将是一个更好的答案。
pppery

1
@pppery Python可读性强,注释确实指示了源文件夹和输出文件夹,其余的读起来像英语。
阿里(Ari)

-1

这是一种不需要其他库且速度非常快的解决方案。可以从以下网址找到它:https : //nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html# 我已在函数中添加了代码以使其更加方便。

def convert(filepath):
    with open(filepath, "rb") as file:
        pdf = file.read()

    startmark = b"\xff\xd8"
    startfix = 0
    endmark = b"\xff\xd9"
    endfix = 2
    i = 0

    njpg = 0
    while True:
        istream = pdf.find(b"stream", i)
        if istream < 0:
            break
        istart = pdf.find(startmark, istream, istream + 20)
        if istart < 0:
            i = istream + 20
            continue
        iend = pdf.find(b"endstream", istart)
        if iend < 0:
            raise Exception("Didn't find end of stream!")
        iend = pdf.find(endmark, iend - 20)
        if iend < 0:
            raise Exception("Didn't find end of JPG!")

        istart += startfix
        iend += endfix
        jpg = pdf[istart:iend]
        newfile = "{}jpg".format(filepath[:-3])
        with open(newfile, "wb") as jpgfile:
            jpgfile.write(jpg)

        njpg += 1
        i = iend

        return newfile

以pdf路径作为参数调用convert,该函数将在同一目录中创建一个.jpg文件


1
这项技术看起来像是提取嵌入在文件中的图像,而不是将文件的页面光栅化为提问者想要的图像。
Josh Gallagher
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.