You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何实现图片适配A4尺寸生成PDF(支持FPDF或Pillow方案)

如何实现图片适配A4尺寸生成PDF(支持FPDF或Pillow方案)

嘿,我来帮你搞定图片适配A4页面的问题!你当前用FPDF的代码确实会遇到超大图片被裁切的情况,咱们分别看看FPDF优化方案Pillow实现方案,两种都能解决你的痛点。


一、优化FPDF代码:自动缩放图片适配A4

首先得明确,FPDF默认的A4页面尺寸是210mm(宽)×297mm(高)。要让图片完整显示,我们需要先获取图片的原始尺寸,然后计算出合适的缩放比例,保证图片缩放后不会超出页面边界(还可以按需加边距)。

这里需要借助Pillow来获取图片的宽高信息,先安装依赖:

pip install fpdf pillow

优化后的代码如下:

from fpdf import FPDF
from PIL import Image

def image_to_pdf(image_url, pdf_url, margin=10):
    # 初始化PDF,设置A4页面
    pdf_model = FPDF(unit="mm", format="A4")
    pdf_model.add_page()
    
    # 获取页面可用尺寸(减去边距)
    page_width = pdf_model.w - 2 * margin
    page_height = pdf_model.h - 2 * margin
    
    # 打开图片获取原始尺寸
    with Image.open(image_url) as img:
        img_width, img_height = img.size
        # 转换图片尺寸单位为mm(FPDF默认DPI是72,和多数图片默认一致)
        img_width_mm = img_width * 25.4 / 72
        img_height_mm = img_height * 25.4 / 72
        
        # 计算缩放比例:取宽、高缩放比例的最小值,保证图片完全适配页面
        scale_width = page_width / img_width_mm
        scale_height = page_height / img_height_mm
        scale = min(scale_width, scale_height)
        
        # 计算缩放后的图片尺寸
        scaled_width = img_width_mm * scale
        scaled_height = img_height_mm * scale
        
        # 计算居中位置(不需要居中的话,把x、y设为margin即可)
        x = (pdf_model.w - scaled_width) / 2
        y = (pdf_model.h - scaled_height) / 2
    
    # 添加缩放后的图片到PDF
    pdf_model.image(image_url, x=x, y=y, w=scaled_width, h=scaled_height)
    pdf_model.output(pdf_url)
    
    return pdf_url

代码说明:

  • 加入了边距设置(默认10mm),避免图片紧贴页面边缘
  • 自动计算缩放比例,保证图片完整显示在A4页面内
  • 支持图片居中显示,也可以轻松改成左上角对齐

二、Pillow方案:先调整图片再生成PDF

如果你更倾向用Pillow,我们可以先创建一个A4尺寸的空白画布,把缩放后的图片粘贴到画布上,最后直接保存为PDF。这种方式更直观,适合对图片处理有更多自定义需求的场景。

先安装依赖:

pip install pillow

实现代码如下:

from PIL import Image

def pillow_image_to_pdf(image_url, pdf_url, dpi=300):
    # A4纸尺寸(毫米)转像素(基于指定DPI,300DPI适合打印)
    a4_width_mm = 210
    a4_height_mm = 297
    a4_width_px = int(a4_width_mm * dpi / 25.4)
    a4_height_px = int(a4_height_mm * dpi / 25.4)
    
    # 打开原始图片
    with Image.open(image_url) as img:
        # 计算缩放比例,保证图片适配A4画布
        scale_width = a4_width_px / img.width
        scale_height = a4_height_px / img.height
        scale = min(scale_width, scale_height)
        
        # 用高质量算法缩放图片,尽量保留画质
        scaled_img = img.resize(
            (int(img.width * scale), int(img.height * scale)),
            Image.Resampling.LANCZOS
        )
        
        # 创建A4尺寸的白色画布
        a4_canvas = Image.new("RGB", (a4_width_px, a4_height_px), "white")
        
        # 计算图片居中粘贴的位置
        paste_x = (a4_width_px - scaled_img.width) // 2
        paste_y = (a4_height_px - scaled_img.height) // 2
        
        # 把缩放后的图片粘贴到画布上
        a4_canvas.paste(scaled_img, (paste_x, paste_y))
        
        # 保存为PDF,指定DPI保证打印清晰度
        a4_canvas.save(pdf_url, "PDF", resolution=dpi)
    
    return pdf_url

代码说明:

  • 基于指定DPI转换A4尺寸为像素,兼顾屏幕显示和打印需求
  • 使用LANCZOS算法缩放图片,最大程度减少画质损失
  • 创建白色背景的A4画布,图片默认居中显示
  • 直接导出为PDF,无需额外的PDF处理库

备注:内容来源于stack exchange,提问作者Seyedmahdi moosavyan

火山引擎 最新活动