You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用FPDF插入JpegImageFile到PDF遇TypeError问题求助

问题

尝试使用FPDF库在PDF中展示多张图片,这些图片以JpegImageFile对象的形式存储在嵌套列表all_pics中。调用self.image方法时出现错误:TypeError: unhashable type: 'JpegImageFile',尝试遍历列表也提示JPEGFileType不可迭代,请问如何将这些图片成功插入PDF?

使用的代码:

from fpdf import FPDF

class FPDF(FPDF):
    def print_images (self, num, all_pics):
        for img in all_pics[num]:
            self.image(img, x = None, y = None, w = 0, h = 0, type = '', link = '')

def main_pdf(num, all_pics, bearing_data):  
    
    if num != 'Select number':
        export = st.button("Export Report")
        if export:
            pdf=FPDF()
            for i in range(num):
                pdf.print_images(i, all_pics)

报错回溯信息:

TypeError: unhashable type: 'JpegImageFile'

Traceback:

File "C:\Users\dksojfab\Anaconda3\envs\Julias_works\lib\site-packages\streamlit\scriptrunner\script_runner.py", line 554, in _run_script
    exec(code, module.__dict__)
File "form_main.py", line 16, in <module>
    conv.main_pdf(num, all_pics, bearing_info)
File "C:\Users\dksojfab\OneDrive - Alfa Laval\Documents\Python Scripts\convert_to_pdf.py", line 106, in main_pdf
    pdf.print_images(i, all_pics)
File "C:\Users\dksojfab\OneDrive - Alfa Laval\Documents\Python Scripts\convert_to_pdf.py", line 94, in print_images
    self.image(img, x = None, y = None, w = 0, h = 0, type = '', link = '')
File "C:\Users\dksojfab\Anaconda3\envs\Julias_works\lib\site-packages\fpdf\fpdf.py", line 150, in wrapper
    return fn(self, *args, **kwargs)
File "C:\Users\dksojfab\Anaconda3\envs\Julias_works\lib\site-packages\fpdf\fpdf.py", line 960, in image
    if not name in self.images:
解决方案

错误原因

FPDF的image()方法不直接支持PIL的JpegImageFile对象:

  1. 该方法默认接受文件路径字符串或二进制文件对象,而非PIL图片实例
  2. 报错中的if not name in self.images是因为FPDF会用第一个参数作为键缓存图片,而JpegImageFile是不可哈希类型,无法作为字典键使用

解决方法

以下两种方法可直接实现需求:

方法1:将JpegImageFile转为BytesIO二进制流(推荐,无需写入磁盘)

引入io模块,把PIL图片对象转为二进制流后传入image(),同时指定图片类型为JPG:

from fpdf import FPDF
import io
from PIL import Image  # 确保导入PIL

class FPDF(FPDF):
    def print_images(self, num, all_pics):
        # 先确认all_pics[num]是可迭代的图片列表
        if not isinstance(all_pics[num], (list, tuple)):
            raise ValueError(f"all_pics[{num}]不是可迭代的图片列表")
        
        for img in all_pics[num]:
            # 将JpegImageFile转为BytesIO
            img_bytes = io.BytesIO()
            img.save(img_bytes, format='JPEG')
            img_bytes.seek(0)  # 重置文件指针到开头
            # 传入二进制流,指定类型为JPG
            self.image(img_bytes, x=None, y=None, w=0, h=0, type='JPG', link='')

def main_pdf(num, all_pics, bearing_data):  
    if num != 'Select number':
        export = st.button("Export Report")
        if export:
            pdf=FPDF()
            for i in range(num):
                pdf.add_page()  # 注意:需要先添加页面才能插入图片
                pdf.print_images(i, all_pics)
            pdf.output("report.pdf")  # 别忘了输出PDF文件

方法2:将JpegImageFile保存为临时文件(适合需要持久化图片的场景)

使用tempfile模块创建临时文件,写入图片后传入文件路径:

from fpdf import FPDF
import tempfile
from PIL import Image

class FPDF(FPDF):
    def print_images(self, num, all_pics):
        if not isinstance(all_pics[num], (list, tuple)):
            raise ValueError(f"all_pics[{num}]不是可迭代的图片列表")
        
        for img in all_pics[num]:
            with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as temp_file:
                img.save(temp_file, format='JPEG')
                temp_path = temp_file.name
            # 传入临时文件路径
            self.image(temp_path, x=None, y=None, w=0, h=0, type='JPG', link='')
            # 可选:删除临时文件
            import os
            os.unlink(temp_path)

def main_pdf(num, all_pics, bearing_data):  
    if num != 'Select number':
        export = st.button("Export Report")
        if export:
            pdf=FPDF()
            for i in range(num):
                pdf.add_page()
                pdf.print_images(i, all_pics)
            pdf.output("report.pdf")

额外注意点

  • 原代码缺少add_page()调用:FPDF默认没有页面,必须先添加页面才能插入内容
  • 确认all_pics的结构:确保all_pics[i]是可迭代的图片列表,避免"JPEGFileType不可迭代"的错误

内容的提问来源于stack exchange,提问作者jufi98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:30:48