首页 > 解决方案 > 如何使用 Python 将内存中的多页图像字节转换为 PDF 或 TIFF 字节?

问题描述

我正在寻找一种解决方案,仅将图像字节转换为内存中的PDF 字节。

对于我的 Web 应用程序,它采用 pdf/tiff 文档(可以是多页的)进行信息提取。

我在管道开始时添加了一个图像预处理步骤。但是,此步骤仅适用于我使用 OpenCV2 的图像。因此,pdf/tiff 文件被转换为图像进行预处理。但是,要发送文件以进行信息提取,我需要将它们重新组合在一起,因为第一页和后续页面的逻辑流程不同。

我以前使用过一种解决方法(引用合并 pdf 的本地路径),但现在我想删除依赖项并在内存中执行所有操作。这样我就可以在云上部署应用程序。

image = Image.open(io.BytesIO(file_str))
num_frames = image.n_frames

# Loop through each page of a tif file
for i in range(num_frames):
    image.seek(i)
    file_array = np.array(image)
    file_array = file_array.astype(np.uint8) * 255

    # Preprocessing (removed for simplicity)

    # TODO: Merge back into PDF file

编辑: 简单的答案:我不能在内存中这样做。相反,我使用 tempfile 库来帮助我将文件保存在那里,并在完成后删除临时目录。这在某种程度上有助于实现“内存”方面。

标签: pythonimagepdfpython-imaging-library

解决方案


使用 Pillow 可以编写(而不是阅读)多页 PDF 文件。对于以下解决方案,我用于pdf2image将一些多页 PDF 文件转换为 PillowImage对象列表。因此,请根据您现有的代码进行调整。

from PIL import Image
import pdf2image
import numpy as np

# Read pages from PDF to Pillow Image objects
frames_in = pdf2image.convert_from_path('path/to/your/file.pdf')

# Enumerate frames, and preprocess
frames_out = []
for i, frame in enumerate(frames_in):

    # Convert to NumPy array
    frame = np.array(frame)

    # Preprocessing for the first page
    if i == 0:
        frame[:100, ...] = [255, 0, 0]

    # Preprocessing for the other pages
    else:
        frame[:100, ...] = [0, 0, 255]

    # Convert back to Pillow Image object, and append to output list
    frames_out.append(Image.fromarray(frame))

frames_out[0].save('output.pdf', save_all=True, append_images=frames_out[1:])

使用一些示例 PDF时,输出看起来相同,但第一页上有一个红色矩形,第二页上有一个蓝色矩形。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
PyCharm:       2021.1.1
NumPy:         1.20.2
pdf2image      1.14.0
Pillow:        8.2.0
----------------------------------------

推荐阅读