Как удалить exif из JPG без потери качества изображения?

У меня есть приложение для обмена фотографиями PHP, в котором пользовательские изображения изменяются в различные форматы большого пальца с помощью ImageMagick.

Как кажущийся «умный» способ сэкономить на размере файла, я удаляю exif-информацию из этих больших пальцев следующим образом:

$imagick = new Imagick($image); $imagick->stripImage(); $imagick->writeImage($image); 

Это работает. Он удаляет информацию EXIF, где превью 30 КБ экономит 12 КБ и становится 18 КБ. Значительная экономия при отображении многих таких больших пальцев на одной странице.

Однако проблема заключается в том, что она работает слишком хорошо. Полученные изображения, похоже, теряют много информации о цвете и выглядят «плоскими» по сравнению с их не раздеваемыми версиями.

Основываясь на моих исследованиях до сих пор, моя теория заключается в том, что верно одно или оба из следующих утверждений:

  • Imagick выбрасывает важную информацию о цветовом профиле как часть процесса вскрыши
  • Imagick повторно сжимает изображение при его сохранении, теряя качество

Независимо от причины проблемы, я ищу способ удалить информацию EXIF ​​таким образом, чтобы она не влияла на качество изображения или цвет.

Возможно ли это?

Обновить:

Основываясь на ответе Джеральда Шнайдера, я попытался установить настройку качества на 100% до «снятия» изображения:

 $imagick = new Imagick($image); $imagick->setCompression(imagick::COMPRESSION_JPEG); $imagick->setCompressionQuality(100); $imagick->stripImage(); $imagick->writeImage($image); 

К сожалению, проблема остается. Ниже приведен пример вывода, который, несмотря на то, что качество 100%, изображения все еще сплющены.

введите описание изображения здесь

Рассмотрите возможность сохранения профиля ICC (который вызывает более насыщенные цвета) при удалении всех других данных EXIF:

  1. Извлечь профиль ICC
  2. Сброс данных EXIF ​​и профиля изображения
  3. Добавить профиль ICC назад

В PHP + imagick:

 $profiles = $img->getImageProfiles("icc", true); $img->stripImage(); if(!empty($profiles)) $img->profileImage("icc", $profiles['icc']); 

(Важное замечание: использование бета-версии ImageMagick 3.1.0, результат, полученный мной из getImageProfiles() немного отличался от документации . Я бы посоветовал играть с параметрами, пока не получится ассоциативный массив с фактическим профилем. )

Для командной строки ImageMagick:

 convert image.jpg profile.icm convert image.jpg -strip -profile profile.icm output.jpg 

Конечно, изображения будут скомпрессированы, если вы используете ImageMagick, но по крайней мере цвета остаются неизменными.

Надеюсь это поможет.

Сделав аналогичные изменения в типах MIME в заголовках файлов, которые были неправильно сохранены, я предлагаю вам проверить длину данных EXIF ​​с помощью стандартных инструментов, а затем «Нуль» данных вручную, используя многобайтовые строковые функции.

EXIF может быть не более 64 КБ в файле JPEG, однако я не уверен, если он будет 64 КБ, поэтому я начну с этого.