如何批量切分长图并整合到一个PDF?
问题描述:
制作底稿时,老板让我去企查查截图快60个交易对方的工商信息截图。网页截图工具截的图是一张张的长图,放一张纸上,打印出来非常不清。有没有一种办法让我可以批量切分我网页截出的长图并直接整合成一个PDF,然后我就可以清晰地打印了?
解决市场痛点:
- 牛马行为:一个交易对方的工商信息一部分一部分地手动截图,太慢太无聊;
- 网页直接截图:打印出来长图在一张纸上,不清晰!
- 牛马行为2号:网页截的长图用线上长图切分工具一个一个切分,在一个一个粘到word,BORING!
准备工作:
pip install pypdf Pillow reportlab
直接上代码:
import os
from PIL import Image
from pypdf import PdfWriter, PdfReader
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from pathlib import Path
# 定义统一的页边距(调整为较小值)
MARGIN = 30 # 页边距,单位为 points (约 10mm)
def split_long_image(image_path, max_height=2000):
"""将长图按指定最大高度切分成多张图片"""
img = Image.open(image_path)
width, height = img.size
if height <= max_height:
return [img], False # 返回图片列表和是否切分标志
num_splits = (height + max_height - 1) // max_height
split_images = []
for i in range(num_splits):
top = i * max_height
bottom = min((i + 1) * max_height, height)
cropped_img = img.crop((0, top, width, bottom))
split_images.append(cropped_img)
return split_images, True # True 表示图片被切分
def image_to_pdf_page(image, temp_pdf_path, is_last_split=False, max_page_width=None, max_page_height=None):
"""将单张图片转换为单页PDF,使用图片原始分辨率并添加一致页边距"""
img_width, img_height = image.size
# 如果 max_page_width 和 max_page_height 未提供,初始化为图片尺寸
if max_page_width is None:
max_page_width = img_width
if max_page_height is None:
max_page_height = img_height
# 计算页面总大小,包含页边距
page_width = max_page_width + 2 * MARGIN
page_height = max_page_height + 2 * MARGIN
# 确保页面大小不小于 A4
min_width, min_height = A4
page_width = max(page_width, min_width)
page_height = max(page_height, min_height)
# 创建一个PDF页面
c = canvas.Canvas(temp_pdf_path, pagesize=(page_width, page_height))
# 计算图片在页面中的位置
x_offset = MARGIN # 水平边距
if is_last_split:
# 最后一个切分部分放在页面顶端,保留上边距
y_offset = page_height - MARGIN - img_height # 从页面顶部开始,保留上边距
else:
# 其他部分垂直居中
y_offset = MARGIN + (max_page_height - img_height) / 2
# 确保图片不超出页面
if x_offset + img_width > page_width:
x_offset = MARGIN
if y_offset + img_height > page_height:
y_offset = MARGIN
# 将图片绘制到PDF
temp_img_path = "temp_img.png" # 使用 PNG 格式避免压缩
image.save(temp_img_path, "PNG")
c.drawImage(temp_img_path, x_offset, y_offset, img_width, img_height)
c.showPage()
c.save()
# 删除临时图片文件
os.remove(temp_img_path)
return page_width, page_height
def images_to_pdf(input_folder, output_pdf_path):
"""将文件夹中的长图切分并整合成PDF,保持图片原始分辨率并统一页边距"""
pdf_writer = PdfWriter()
image_extensions = ('.jpg', '.jpeg', '.png', '.bmp')
image_files = sorted([
f for f in os.listdir(input_folder)
if f.lower().endswith(image_extensions)
])
max_page_width = 0
max_page_height = 0
# 首先确定所有图片的最大宽度和高度
for image_file in image_files:
image_path = os.path.join(input_folder, image_file)
try:
img = Image.open(image_path)
img_width, img_height = img.size
max_page_width = max(max_page_width, img_width)
# 考虑切分后的最大高度
num_splits = (img_height + 2000 - 1) // 2000
max_page_height = max(max_page_height, min(2000, img_height))
except Exception as e:
print(f"读取 {image_file} 大小时出错: {str(e)}")
for image_file in image_files:
image_path = os.path.join(input_folder, image_file)
try:
# 切分长图
split_images, was_split = split_long_image(image_path)
# 将每张切分后的图片转换为PDF并添加到最终PDF
for idx, img in enumerate(split_images):
if img.mode != 'RGB':
img = img.convert('RGB')
# 判断是否是最后一个切分部分
is_last_split = was_split and (idx == len(split_images) - 1)
temp_pdf_path = f"temp_{image_file}_{idx}.pdf"
page_width, page_height = image_to_pdf_page(img, temp_pdf_path, is_last_split, max_page_width, max_page_height)
temp_pdf = PdfReader(temp_pdf_path)
for page in temp_pdf.pages:
pdf_writer.add_page(page)
os.remove(temp_pdf_path)
print(f"已处理: {image_file}")
except Exception as e:
print(f"处理 {image_file} 时出错: {str(e)}")
with open(output_pdf_path, 'wb') as output_file:
pdf_writer.write(output_file)
print(f"PDF已保存至: {output_pdf_path}")
def main():
input_folder = r"C:\Users\jztxz\Desktop\文件夹A"
output_pdf = r"C:\Users\jztxz\Desktop\文件夹A_output.pdf"
if not os.path.exists(input_folder):
print(f"错误:文件夹 {input_folder} 不存在")
return
images_to_pdf(input_folder, output_pdf)
if __name__ == "__main__":
main()
注意:
- 我用的是 pypdf,就是那个 PyPDF2 的 fork,更新和支持更好。
- 我的长图都放在了桌面文件夹A中,位置是"C:\Users\jztxz\Desktop\文件夹A.pdf"。请注意更改代码中文件夹A的位置为你长图所在文件夹位置。
希望这篇文章可以帮到大家!祝看到这里的有缘人早日达到自己要去的地方