Проверка, является ли формат изображения Lossless в Python?
Я работаю над приложением, которое требует, чтобы изображения, представленные в нем, были без потерь. В настоящее время я открываю изображение с помощью PIL и проверяю, является ли атрибут "format" форматом без потерь. Это требует, чтобы я вручную вел список форматов, и я понятия не имею, если, например, к представленному jpeg просто применен вариант без потерь.
import PIL
import PIL.Image
def validate_image(path):
img = PIL.Image.open(path)
if not img.format.lower() in ['bmp', 'gif', 'png', ...]:
raise Exception("File %s has invalid image format %s" % (path, img.format))
Есть ли лучший способ проверить, является ли файл изображения без потерь?
1 ответ
Я думаю, что теперь я понимаю вещи: вы хотите, чтобы открыть изображения через PIL. Вы хотите отказаться от изображений с потерями, потому что вы выполняете научную обработку, которая требует все потерянные данные, потому что информация, которая не важна для визуальной обработки человеком, важна для ваших алгоритмов.
PIL не имеет какого-либо интерфейса на верхнем уровне, чтобы различать различные типы сжатия. Вы можете добраться до декодеров изображений и предположить, что все, что использует "сырой" декодер, без потерь, но даже если вы захотите это сделать, это слишком ограничено - оно исключит GIF, LZW-сжатый TIFF и т. Д. Вместе с JPEG, JPEG-сжатый TIFF и т. Д.
Имейте в виду, что настоящая проблема здесь - это обмен сообщениями и документирование - управление ожиданиями пользователей. Проверка изображений с потерями - на самом деле просто эвристика, способ уловить более очевидные ошибки и напомнить пользователю, каковы требования. Таким образом, вам не нужно что-то идеальное, но в любом случае полезно что-то очень хорошее.
Итак, вариантов всего несколько, ни один из них не очень хорош:
Взломайте источник декодера PIL, чтобы сохранить информацию о кодировке и передать ее на верхний уровень. Очевидно, что это займет некоторую нетривиальную работу с 30 различными импортерами, возможно, с участием как C, так и Python, и это приведет к появлению патча, который вы должны будете поддерживать против (медленно) развивающейся кодовой базы - хотя Конечно, вы всегда можете отправить его в апстрим и надеяться, что это войдет в будущие версии PIL.
Покопайтесь в самих декодерах, чтобы получить информацию во время выполнения. Единственная полустандартная вещь, которую вы действительно можете найти, это то, используют ли они необработанный декодер или битовый декодер, что совершенно бесполезно (многим форматам без потерь понадобится битовый декодер), так что вы, вероятно, в конечном итоге прочитаете все 30 импортеры и написание дюжины или около того кусочков кода для извлечения информации из них.
Используйте другую библиотеку вместе с (или вместо) PIL. Например, хотя ImageMagick определенно не намного проще, чем PIL, у него есть API, который сообщает вам, какой тип сжатия использует файл изображения. В основном, если это
UndefinedCompression
или жеJPEGCompression
это потеря, все остальное, это без потерь. Основным недостатком (помимо необходимости установки двух библиотек изображений) является наличие файлов, которые PIL может открывать, но IM не может, и наоборот, и файлов с несколькими изображениями, которые PIL и IM обрабатывают по-разному, и так далее.Делай то, что ты уже делаешь. Прочитайте 30 импортеров, чтобы составить список с потерями и без потерь. Для обработки таких случаев, как JPEG и TIFF, которые иногда бывают без потерь, вы можете написать код, который не отклоняет их, а вместо этого выдает предупреждение "Эти файлы могут быть с потерями. Вы уверены, что хотите импортировать их?" (Или, в качестве альтернативы, просто предложите переопределение "Я знаю, что я делаю" для всех форматов с потерями, а затем просто рассмотрите потери с JPEG и TIFF.)
Для многих случаев использования я бы очень осторожно выбрал #4, но для вашего, на самом деле, это кажется довольно разумным. Вы не пытаетесь заблокировать изображения с потерями, потому что ваш код падает, или по соображениям безопасности, или что-то подобное; вы просто пытаетесь предупредить людей, что они будут тратить много времени на получение бесполезной информации, если они отправят JPEG, верно?