У меня возникла проблема с добавлением новых тегов в данные Exif для изображения.
Настройка
Я создал скрипт Python PySimpleGUI для простых манипуляций с изображениями и проработал все, кроме последних шагов.
Скрипт отображает изображение (jpg, jepg) и ключевые данные Exif. Сценарий использует серию флажков для быстрого «пометки» и изображения из выбранного (списка). У меня есть набор флажков, изображение обновляется правильно. Таким образом, я могу правильно декодировать данные Exif, но когда я хочу обновить изображение, у меня возникают проблемы.
Я использую Windows 10 с Python3, с импортом из PIL, PySimpleGUI.
Мета-данные:
- 40094 (идентификатор Exif для ключа, который я хочу обновить)
- Exif.Image.XPKeywords
- Байт (тип переменной)
- Тег ключевых слов, используемый Windows (в кодировке UCS2)
Я нашел помощь: Кодировать UCS2
Используя помощь сверху, я могу получить следующее:
Exif: b'O\x00u\x00t\x00d\x00o\x00o\x00r\x00;\x00a\x00r\x00t\x00\x00\x00'
Преобразуется в Outdoor;art
<i = 40094>
img = Image.open(pathname + '\\' + filename)
exifDataRaw = img._getexif()
if exifDataRaw.get(i):
if exifDataRaw[i]:
print("Exif:", exifDataRaw[i])
return str(exifDataRaw[i].decode('utf-16'))
Хорошо, я могу преобразовать этот str
в список и обновить флажки.
Обновление тегов (ключевых слов)
Я добавляю дополнительные ключевые слова в str
. Сейчас: Outdoor;art;box;machine;
Для обновления ключей у меня есть эта функция. Установленные флажки имеют значение "Истина", а невыделенные флажки - значение "Ложь". PySimpleGUI as собирает события и значения. Функция просматривает значения для выбранного «True». TaggerList - это главный список тегов, которые я использую в скрипте. Когда флажок установлен в True, цикл добавляет теги в InsertString
. Показано выше.
def PushTags(pathname, filename):
InsertString = ""
img = Image.open(pathname + '\\' + filename)
for Tag in TaggerList[:-1]:
if values[Tag]:
InsertString = InsertString + Tag + ";"
first = False
#Get whole dataset
exifDataRaw = img._getexif()
i = 40094
# Set new data to Exif
exifDataRaw[i] = InsertString[:-1].encode('utf-16') # remove the last ";" and encode
img.save(pathname + '\\' + filename, exif=exifDataRaw) #Update image with new values
Я могу использовать Image.Exif.__setitem__(i, InsertString[:-1].encode('utf-16'))
, чтобы сохранять только обновленные ключевые слова.
Но кодировка все равно выдает ошибку.
Оригинал: Exif: b'O\x00u\x00t\x00d\x00o\x00o\x00r\x00;\x00a\x00r\x00t\x00\x00\x00'
Сохраненные теги: b'\xff\xfeu\x00t\x00d\x00o\x00o\x00r\x00;\x00a\x00r\x00t\x00;\x00b\x00o\x00x\x00;\x00m\x00a\x00c\x00h\x00i\x00n\x00e\x00'
Кодирование не кажется взаимным в обоих направлениях. Закодированная строка добавляет '\xff\xfeu
Я предполагаю, что \ xfeu - это заглавная «О».
Кодировка неправильная, изображение ломается. Обычные программы просмотра изображений выдают ошибку при обновлении изображения.
Если я смогу это исправить, я смогу закончить сценарий.
\xff\xfe
- метка порядка байтов и необязательная часть кодирования. - person Klaus D.   schedule 10.06.2020O\x00u...
- person Richard E   schedule 11.06.2020