Img2pdf图片旋转问题:原理与解决方案
2025-02-05 09:10:47
img2pdf图片旋转问题解析与方案
将图片转换为PDF格式时,一个常见的问题是图片本身的EXIF信息中可能包含旋转角度。如果img2pdf
在处理这类图片时,没有按照EXIF信息正确地旋转图片,而是在PDF页面级别设置了旋转,会导致在某些PDF阅读器中显示不正确,或者在后续处理PDF文件时出现意外。目标是让img2pdf
根据EXIF旋转图片本身,并生成无旋转属性的PDF页面。
问题根源:EXIF与PDF旋转的冲突
img2pdf
的 rotation=img2pdf.Rotation.ifvalid
参数的设计目的是,如果EXIF数据中包含旋转信息,则根据此信息旋转图片。但实际应用中,可能会出现以下几种情况:
- 库版本问题 : 早期版本的
img2pdf
在处理EXIF旋转信息时可能存在bug,或者对某些EXIF格式的支持不完整。 - EXIF数据格式 : EXIF旋转信息的格式不统一,某些格式可能无法被
img2pdf
正确解析。 - 与其他参数的冲突 : 某些参数的组合使用可能会干扰
rotation
参数的生效。
即使img2pdf
能够读取并处理EXIF旋转信息,它也可能选择不在图片层面进行旋转,而是在PDF页面层面设置旋转属性。 这与我们期望的输出结果有所偏差。
解决方案一:手动处理EXIF信息,预先旋转图片
如果img2pdf
无法正确处理EXIF旋转,一个可靠的方案是在使用img2pdf
之前,先读取EXIF信息,然后使用图像处理库(如PIL
,Pillow
)手动旋转图片。
步骤:
- 使用
PIL
或Pillow
读取图片,并提取EXIF数据。 - 解析EXIF数据,获取旋转角度。
- 根据旋转角度旋转图片。
- 将旋转后的图片传递给
img2pdf
进行PDF转换。
代码示例:
from io import BytesIO
from PIL import Image, ExifTags
import img2pdf
import requests
def rotate_image(image_bytes):
"""
读取图片,解析EXIF旋转信息,并旋转图片。
"""
image = Image.open(BytesIO(image_bytes))
try:
for orientation in ExifTags.TAGS.keys():
if ExifTags.TAGS[orientation] == 'Orientation':
break
exif = image._getexif()
if exif and orientation in exif:
orientation = exif[orientation]
if orientation == 3:
image = image.rotate(180, expand=True)
elif orientation == 6:
image = image.rotate(-90, expand=True) # 注意方向
elif orientation == 8:
image = image.rotate(90, expand=True) # 注意方向
except (AttributeError, KeyError, IndexError):
# 没有EXIF信息
pass
return image
def convert_image_to_pdf(image_bytes):
"""
转换图片到PDF,且图片根据EXIF信息完成旋转
"""
rotated_image = rotate_image(image_bytes)
img_byte_arr = BytesIO()
rotated_image.save(img_byte_arr, format='JPEG')
img_byte_arr = img_byte_arr.getvalue()
pdf_bytes = img2pdf.convert(img_byte_arr) # 删除rotation参数
return pdf_bytes
# 下载测试图片
response = requests.get("https://drive.google.com/file/d/1JyCBl5ulQmKIdQnVsvbNo7oNHX7oGIda/view?usp=sharing", stream=True)
response.raise_for_status()
image_data = response.content
# 测试函数
pdf_data = convert_image_to_pdf(image_data)
with open('output.pdf', 'wb') as f:
f.write(pdf_data)
要点:
- 在
img2pdf.convert()
中,不要再使用rotation
参数,确保PDF页面不被额外旋转。 - 这段代码的核心是
rotate_image
函数,它负责从 EXIF 数据中提取旋转信息并实际旋转图像。请确保安装PIL
或Pillow
模块。
解决方案二:利用图像处理工具,批量转换图像并去除旋转
这个方法针对已有大量需要转换的图片,可以事先通过命令行工具将它们全部按照正确的方向存储。比如利用 ImageMagick
等工具来达成目的。
步骤:
- 安装
ImageMagick
- 利用
mogrify
命令读取图片,旋转图片并覆盖原文件,去除 EXIF 信息:mogrify -auto-orient *.jpg # 根据EXIF旋转所有jpg图片并覆盖 mogrify -strip *.jpg # 去除EXIF信息, 可以节省文件空间
代码示例:
无代码示例,这是一个纯命令行操作的方法。
注意:
该方法会修改原始图像文件。建议在操作前备份原始数据,避免数据丢失。也可以使用 convert
命令将处理结果保存为新的文件,以保留原始文件。 例如:convert input.jpg -auto-orient output.jpg
总结
上述两个方案都旨在解决 img2pdf
在处理带有EXIF旋转信息的图片时可能出现的问题。首选的方案是预处理图片,确保传递给 img2pdf
的是已经正确旋转的图片,这样可以避免PDF页面级别的旋转属性,获得更可控的输出结果。选择哪一种方法取决于具体需求。