如何实现图片适配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




