Python python-docx 插入图片兼容性测试——解决docx.image.exceptions.UnrecognizedImageError

问题描述

1.jpg

使用 Webp 转换器 转换为 1.webp

from docx import Document

document = Document()
document.add_picture('1.webp')
document.save('test.docx')

报错 docx.image.exceptions.UnrecognizedImageError,发现该图片的 mime_type 为 image/webp ,这是一种浏览器压缩图片的格式

查看源码,image.py 会从 SIGNATURES 读取不同格式的图像文件




安装

pip install python-docx
pip install python-magic

Windows 下还要

pip install python-magic-bin




代码

使用 图像转换器 对 1.jpg 进行不同图像格式转换

mime_type

import magic

files = ['1.jpg', '1.png', '1.jfif', '1.gif', '1.tiff', '1.bmp', '1.eps', '1.hdr', '1.ico', '1.svg', '1.tga', '1.wbmp', '1.webp']
for file in files:
    print(file, magic.from_file(file, mime=True))
# 1.jpg image/jpeg
# 1.png image/png
# 1.jfif image/jpeg
# 1.gif image/gif
# 1.tiff image/tiff
# 1.bmp image/x-ms-bmp
# 1.eps application/postscript
# 1.hdr application/octet-stream
# 1.ico image/x-icon
# 1.svg image/svg+xml
# 1.tga image/x-tga
# 1.wbmp application/octet-stream
# 1.webp image/webp

能否插入

from docx import Document

document = Document()
document.add_picture('1.jpg')
document.add_picture('1.png')
document.add_picture('1.jfif')
# document.add_picture('1.exif')
document.add_picture('1.gif')
document.add_picture('1.tiff')
document.add_picture('1.bmp')

document.add_picture('1.eps')
document.add_picture('1.hdr')
document.add_picture('1.ico')
document.add_picture('1.svg')
document.add_picture('1.tga')
document.add_picture('1.wbmp')
document.add_picture('1.webp')
document.save('test.docx')

结论

图片格式mime_type能否插入
.jpgimage/jpeg
.pngimage/png
.jfifimage/jpeg
.exif
.gifimage/gif
.tiffimage/tiff
.bmpimage/x-ms-bmp
.epsapplication/postscript×
.hdrapplication/octet-stream×
.icoimage/x-icon×
.svgimage/svg+xml×
.tgaimage/x-tga×
.wbmpapplication/octet-stream×
.webpimage/webp×




解决方案

方案一、转换格式

将其他格式转换成可插入的类型,如 .jpg

安装

pip install pillow

代码

import io
from pathlib import Path

import magic
from PIL import Image


def image_to_jpg(image_path_or_stream):
    """使用Pillow将不支持的图片文件转换为.jpg文件"""
    f = io.BytesIO()
    if isinstance(image_path_or_stream, str):
        path = Path(image_path_or_stream)
        if path.suffix in {'.jpg', '.png', '.jfif', '.exif', '.gif', '.tiff', '.bmp'}:
            f = open(image_path_or_stream, mode='rb')
        else:
            Image.open(image_path_or_stream).convert('RGB').save(f, format='JPEG')
    else:
        buffer = image_path_or_stream.read()
        mime_type = magic.from_buffer(buffer, mime=True)
        if mime_type in {'image/jpeg', 'image/png', 'image/gif', 'image/tiff', 'image/x-ms-bmp'}:
            f = image_path_or_stream
        else:
            Image.open(io.BytesIO(buffer)).convert('RGB').save(f, format='JPEG')
    return f


if __name__ == '__main__':
    from docx import Document

    document = Document()
    document.add_picture(image_to_jpg('1.jpg'))
    document.add_picture(image_to_jpg('1.webp'))
    document.add_picture(image_to_jpg(open('1.jpg', mode='rb')))
    document.add_picture(image_to_jpg(open('1', mode='rb')))  # 将1.webp拷贝一份并改名为1
    document.save('test.docx')




方案二、修改库代码

先尝试能否手动插入到 Word 文档,可以的话证明支持这种格式,再自行修改库,继承 BaseImageHeader 类,实现 from_stream() 方法,并在 SIGNATURES 中加入该图片格式




插入没有后缀的文件提示【当前无法显示此图像。】

将 1.jpg 改名为 1

from docx import Document

document = Document()
document.add_picture('1')
document.save('test.docx')

效果

改成这样即可

from docx import Document

document = Document()
document.add_picture(open('1', mode='rb'))
document.save('test.docx')




封装




参考文献

  1. Python操纵Word神器——python-docx大全(含插入pptx图表)
  2. Python文件类型识别——python-magic
  3. python-docx/image.py
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XerCis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值