【问题标题】:Python's exif module and Umlauts in JPEG MetadataPython 的 exif 模块和 JPEG 元数据中的元音变音
【发布时间】:2021-04-19 12:52:30
【问题描述】:

我正在编写一个小脚本,它可以帮助我使用 Python3 中的 exif 模块在 Python 中编辑 JPEG 文件的 EXIF 元数据,尤其是“艺术家”字段。但是,由于我是德国人,我必须处理一些作者字段包含变音符号的文件,例如“ü”。如果我现在以'rb' 模式打开其中一个文件,使用myimgobj=Image(myfile) 创建一个exif Image 对象并尝试访问myimgobj.artist,我会得到一长串多个(!)UnicodeDecodeErrrors,它们基本上都是一样的:

'ascii' codec can't decode byte 0xc3 in position 9: ordinal not in range(128)

对于某些错误信息,不是位置 9,而是位置 0,但我想这都可以追溯到同一个原因 - 元音变音。如果现场没有变音符号,一切正常。 有什么方法可以使用 exif 包并提取艺术家,即使它包含变音符号?

编辑:为了提供一个最小的示例,请考虑将艺术家字段设置为“ä”的任何 JPEG 图像(我会上传一个,但 EXIF 标记在上传过程中会被删除)。例如,当我尝试像这样打印艺术家时,它会失败:

from exif import Image
with open('Umlaut.jpg','rb') as imgfile:
    my_image=Image(imgfile)
    print(my_image.artist)

【问题讨论】:

  • edit您的问题提供minimal reproducible example
  • EXIF 只有极少数允许非 ASCII 的字段,但这并不妨碍其他软件仅将 ISO-8859-1 写入大多数字段。在读取 EXIF 时,您需要防止将任何内容转换为 Unicode/UTF-8,而是尝试将其视为 ISO-8859-1(用于德语)。
  • @JosefZ 完成,抱歉 - 我以为已经很清楚了。
  • @AmigoJack 好的,我该怎么做,在 Python 中使用 exif 模块?有没有办法告诉它如何处理字符串?我认为尝试解码字符串(使用 my_image.artist.decode(...))不会有帮助,因为从文件读取时已经出现错误,对吗?
  • 不,没有“一种”方式。只有启发式、反复试验 - 请参阅 stackoverflow.com/a/90916/4299358。在您的情况下,它可能是 ISO-8859-1,但您无法可靠地判断。

标签: python utf-8 jpeg exif


【解决方案1】:

使用以下内容:

import exifread

with open('Umlaut.jpg','rb') as imgfile:
    tags = exifread.process_file(imgfile)

print(tags)                     # all tags

for i,tag in enumerate(tags):
    print(i,tag, tags[tag])     # tag by tag

结果,使用手动插入作者的字符串äüà (== b'\xc3\xa4\xc3\xbc\xc3\x83'.decode('utf8')) 进行测试:.\SO\65720067.py

{'Image Artist': (0x013B) ASCII=äüà @ 2122, 'Image ExifOffset': (0x8769) Long=2130 @ 30, 'Image XPAuthor': (0x9C9D) Byte=äüà @ 4210, 'Image Padding': (0xEA1C) Undefined=[] @ 62, 'EXIF Padding': (0xEA1C) Undefined=[] @ 2148}
0 Image Artist äüÃ
1 Image ExifOffset 2130
2 Image XPAuthor äüÃ
3 Image Padding []
4 EXIF Padding []

根据这些事实,您可以将代码更改为

from exif import Image

with open('Umlaut.jpg','rb') as imgfile:
    my_image=Image(imgfile)

# print(my_image.artist)          # error described below
print(my_image.xp_author)         # äüà   as expected

顺便说一句,运行您的代码不变,会发生以下情况(其中每个 水平省略号代表完整错误回溯中的一堆消息):

…
+--------+-----------+-------+----------------------+------------------+
| Offset | Access    | Value | Bytes                | Type             |
+--------+-----------+-------+----------------------+------------------+
|        |           |       |                      | AsciiZeroTermStr |
|        | [0:0]     | ''    |                      |                  |
| 0      | --error-- |       | c3 a4 c3 bc c3 83 00 |                  |
+--------+-----------+-------+----------------------+------------------+

UnicodeDecodeError occurred during unpack operation:

'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
…
+--------+-----------+-------+-------------------+----------+
| Offset | Access    | Value | Bytes             | Type     |
+--------+-----------+-------+-------------------+----------+
|        |           |       |                   | AsciiStr |
|        | [0:0]     | ''    |                   |          |
| 0      | --error-- |       | c3 a4 c3 bc c3 83 |          |
+--------+-----------+-------+-------------------+----------+

UnicodeDecodeError occurred during unpack operation:

'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

【讨论】:

    猜你喜欢
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 2018-01-14
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    相关资源
    最近更新 更多