要优化代码以保留图片原有的尺寸大小,我们可以修改insert_image_to_pdf
函数,使其自动获取图片的原始尺寸并根据需要调整插入大小。以下是优化后的代码:
from PyPDF2 import PdfReader, PdfWriter
from reportlab.lib.utils import ImageReader
from reportlab.pdfgen import canvas
from io import BytesIO
import os
from PIL import Image
def insert_image_to_pdf(input_pdf_path, output_pdf_path, image_path, x, y, width=None, height=None):
"""
在PDF文件的指定位置插入图片,保留图片原始比例
参数:
input_pdf_path: 输入PDF文件路径
output_pdf_path: 输出PDF文件路径
image_path: 要插入的图片路径
x: 图片左下角x坐标(点)
y: 图片左下角y坐标(点)
width: 图片宽度(点),如为None则使用原始宽度
height: 图片高度(点),如为None则使用原始高度
"""
# 读取原始PDF
reader = PdfReader(input_pdf_path)
writer = PdfWriter()
# 获取PDF页面尺寸
page = reader.pages[0]
page_width = page.mediabox.width
page_height = page.mediabox.height
# 获取图片原始尺寸
with Image.open(image_path) as img:
img_width, img_height = img.size # 获取像素尺寸
img_ratio = img_width / img_height # 宽高比
# 转换为点单位(假设图片DPI为72,1点=1像素)
# 如果需要更精确的DPI转换,可以根据实际图片DPI调整
original_width_pt = img_width
original_height_pt = img_height
# 确定最终使用的宽度和高度
if width is not None and height is not None:
# 如果同时指定了宽高,使用指定值
final_width = width
final_height = height
elif width is not None:
# 如果只指定了宽度,按比例计算高度
final_width = width
final_height = final_width / img_ratio
elif height is not None:
# 如果只指定了高度,按比例计算宽度
final_height = height
final_width = final_height * img_ratio
else:
# 如果都没指定,使用原始尺寸
final_width = original_width_pt
final_height = original_height_pt
# 创建临时PDF页面用于绘制图片
packet = BytesIO()
c = canvas.Canvas(packet, pagesize=(page_width, page_height))
# 绘制图片到指定位置
img = ImageReader(image_path)
c.drawImage(img, x, y, width=final_width, height=final_height, mask='auto', preserveAspectRatio=True)
c.save()
# 将临时PDF与原始PDF合并
packet.seek(0)
new_pdf = PdfReader(packet)
page.merge_page(new_pdf.pages[0])
# 添加处理后的页面到输出
writer.add_page(page)
# 写入输出文件
with open(output_pdf_path, "wb") as output_pdf:
writer.write(output_pdf)
# 使用示例
if __name__ == "__main__":
# 输入文件路径
input_pdf = r"C:\Leon\python_project\oceanxecm\2025\06\20250604-Dusty-BCM\pdf\BCM_test_first_page.pdf"
output_pdf = r"C:\Leon\python_project\oceanxecm\2025\06\20250604-Dusty-BCM\pdf\merged_output.pdf"
image_file = r"C:\Leon\python_project\oceanxecm\2025\06\20250604-Dusty-BCM\png\BCM_pdf_last_img.png"
# 插入图片参数 (x, y, width, height)
# 现在可以只指定宽度或高度,另一个会自动按比例计算
# 或者都不指定,使用原始尺寸
insert_image_to_pdf(input_pdf, output_pdf, image_file, 50, 50, width=200) # 只指定宽度
print(f"图片已成功插入到 {output_pdf}")
主要优化点:
- 使用Pillow库(
Image.open
)获取图片的原始尺寸和宽高比 - 修改函数参数,使width和height变为可选参数
- 添加逻辑处理不同情况:
- 同时指定width和height:使用指定值
- 只指定width:按比例计算height
- 只指定height:按比例计算width
- 都不指定:使用图片原始尺寸
- 在
drawImage
方法中添加preserveAspectRatio=True
参数确保即使指定了尺寸也保持宽高比
现在你可以:
- 只指定宽度或高度,另一个会自动按比例计算
- 或者都不指定,使用图片原始尺寸
- 或者同时指定宽高(但会拉伸图片,不推荐)
注意:代码假设图片DPI为72(1像素=1点),如果图片有不同DPI,需要相应调整转换比例。