智能尺寸PDF图片插入工具

要优化代码以保留图片原有的尺寸大小,我们可以修改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}")

主要优化点:

  1. 使用Pillow库(Image.open)获取图片的原始尺寸和宽高比
  2. 修改函数参数,使width和height变为可选参数
  3. 添加逻辑处理不同情况:
    • 同时指定width和height:使用指定值
    • 只指定width:按比例计算height
    • 只指定height:按比例计算width
    • 都不指定:使用图片原始尺寸
  4. drawImage方法中添加preserveAspectRatio=True参数确保即使指定了尺寸也保持宽高比

现在你可以:

  • 只指定宽度或高度,另一个会自动按比例计算
  • 或者都不指定,使用图片原始尺寸
  • 或者同时指定宽高(但会拉伸图片,不推荐)

注意:代码假设图片DPI为72(1像素=1点),如果图片有不同DPI,需要相应调整转换比例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值