使用ImageMagick将PDF页面保存为图像

5 投票
3 回答
13359 浏览
提问于 2025-04-18 06:49

我想用imagemagick的Wand包把一个PDF文件的所有页面转换成一张图片。不过我遇到了一些问题(下面的评论中有提到这些问题)。

import tempfile
from wand.image import Image


with file('my_pdf_with_5_pages.png') as f:
    image = Image(file=f, format='png')
    save_using_filename(image)
    save_using_file(image)

def save_using_filename(image):
    with tempfile.NamedTemporaryFile() as temp:
        # this saves all pages, but a file for each page (so 3 files)
        image.save(filename=temp.name)

def save_using_file(image):
    with tempfile.NamedTemporaryFile() as temp:
        # this only saves the first page as an image
        image.save(file=temp)

我的最终目标是能够指定哪些页面要转换成一张连续的图片。这在命令行中可以做到,只需要一些

convert -append input.pdf[0-4]

但我现在想用Python来实现。

我看到我们可以通过这样的方法来获取页面的切片:

[x for x in w.sequence[0:1]] # get page 1 and 2

现在的问题是如何把这些页面合并在一起。

3 个回答

1

注意:这会导致内存泄漏

我找到了一种方法。可能还有更好的方法,但这个方法可以用。

class Preview(object):
    def __init__(self, file):
        self.image = Image(file=file)

    def join_pages(self, page_count):
        canvas = self.create_canvas(page_count=page_count)
        for page_number in xrange(page_count):
            canvas.composite(
                self.image.sequence[page_number],
                top=self.image.height*page_number,
                left=0,
            )

    def create_canvas(self, page_count):
        return Image(
            width=self.pdf.width,
            height=self.image.height*page_count,
        )

    preview = Preview(open('path/to/pdf')
    preview.join_pages(3)
11

我的解决方案:

from wand.image import Image

diag='yourpdf.pdf'

with(Image(filename=diag,resolution=200)) as source:
    images=source.sequence
    pages=len(images)
    for i in range(pages):
        Image(images[i]).save(filename=str(i)+'.png')

这个方法有效,而且跟其他答案比起来,它对一些多页的PDF文件更灵活,因为这些文件的每一页大小可能不同。

10

这是对@rikAtee回答的一个小简化,增加了一个功能,可以通过计算序列的长度来自动检测页面数量:

def convert_pdf_to_png(blob):
    pdf = Image(blob=blob)

    pages = len(pdf.sequence)

    image = Image(
        width=pdf.width,
        height=pdf.height * pages
    )

    for i in xrange(pages):
        image.composite(
            pdf.sequence[i],
            top=pdf.height * i,
            left=0
        )

    return image.make_blob('png')

我没有发现任何内存链接的问题,不过我的PDF文件通常只有2到3页。

撰写回答