Python: извлечение кириллической строки из EXIF
Я полный новичок в Python, и хотел бы начать изучать его, делая. А именно, я хотел бы исправить некоторую информацию EXIF в огромной куче семейных фотографий, которые у меня есть. Для начала я хочу просто правильно извлечь эту информацию из файлов JPEG.
Некоторые из них имеют название, написанное на языке EXIF. Его можно получить, например, с помощьюimport pyexiv2
metadata = pyexiv2.ImageMetadata(filename)
metadata.read()
title = metadata['Exif.Image.XPTitle']
Вот до чего я дошел. Теперь возникает проблема. Некоторые названия содержат кириллические буквы. Если я делаю print title.human_value
, я получаю, например
`Милой Мамуле от Майи, 11 ÑÐ½Ð²Ð°Ñ€Ñ 1944.`
В то время как с print title
, это
<Exif.Image.XPTitle [Byte] = 28 4 56 4 59 4 62 4 57 4 32 0 28 4 48 4 60 4 67 4 59 4 53 4 32 0 62 4 66 4 32 0 28 4 48 4 57 4 56 4 44 0 32 0 49 0 49 0 32 0 79 4 61 4 50 4 48 4 64 4 79 4 32 0 49 0 57 0 52 0 52 0 46 0 0 0>
Фактическая строка, которую я хотел бы увидеть, это
Милой Мамуле от Майи, 11 января 1944.
Кажется, это проблема unicode, но после того, как я попробовал уже дюжину различных методов, найденных здесь и в других местах, я просто не могу справиться с ней. Можно ли вообще увидеть русские буквы в консоли? Я использую python (xy) в Windows 7 (английский), поэтому моя IDE-spyder2. Просто установка по умолчанию, к которой я добавил pyexiv2. ТИА!2 ответа:
Байты-это UTF-16.
В Python 3:
>>> b = [28, 4, 56, 4, 59, 4, 62, 4, 57, 4, 32, 0, 28, 4, 48, 4, 60, 4, 67, 4, 59, 4, 53, 4, 32, 0, 62, 4, 66, 4, 32, 0, 28, 4, 48, 4, 57, 4, 56, 4, 44, 0, 32, 0, 49, 0, 49, 0, 32, 0, 79, 4, 61, 4, 50, 4, 48, 4, 64, 4, 79, 4, 32, 0, 49, 0, 57, 0, 52, 0, 52, 0, 46, 0, 0, 0] >>> bytes(b).decode("utf-16") 'Милой Мамуле от Майи, 11 января 1944.\x00'
В Python 2:
>>> b = [28, 4, 56, 4, 59, 4, 62, 4, 57, 4, 32, 0, 28, 4, 48, 4, 60, 4, 67, 4, 59, 4, 53, 4, 32, 0, 62, 4, 66, 4, 32, 0, 28, 4, 48, 4, 57, 4, 56, 4, 44, 0, 32, 0, 49, 0, 49, 0, 32, 0, 79, 4, 61, 4, 50, 4, 48, 4, 64, 4, 79, 4, 32, 0, 49, 0, 57, 0, 52, 0, 52, 0, 46, 0, 0, 0] >>> "".join(chr(c) for c in b).decode("utf-16") u'\u041c\u0438\u043b\u043e\u0439 \u041c\u0430\u043c\u0443\u043b\u0435 \u043e\u04 42 \u041c\u0430\u0439\u0438, 11 \u044f\u043d\u0432\u0430\u0440\u044f 1944.\x00'
Я думаю, название.данные human_value находятся в UTF-8, уже декодированные из необработанных UTF-16 байт заголовка.
В оболочке python, запущенной в окне терминала на OSX:
>>> # this should be the same as your title.human_value: >>> print ''.join( chr(x) for x in [208, 156, 208, 184, 208, 187, 208, 190, 208, 185, 32, 208, 156, 208, 176, 208, 188, 209, 131, 208, 187, 208, 181, 32, 208, 190, 209, 130, 32, 208, 156, 208, 176, 208, 185, 208, 184, 44, 32, 49, 49, 32, 209, 143, 208, 189, 208, 178, 208, 176, 209, 128, 209, 143, 32, 49, 57, 52, 52, 46]) Милой Мамуле от Майи, 11 января 1944.
Ваша консоль может не поддерживать кириллицу. Вы можете попробовать установить шрифт в командной строке в "Lucida Console" - более современный векторный шрифт, скорее всего, будет поддерживать его правильно, чем исторические растровые шрифты, к которым по умолчанию применяется cmd.