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


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

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

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

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

Проблема, однако, в том, что это немного работает слишком хорошо. Результирующие изображения, похоже, теряют много цветовой информации и выглядят "плоскими" по сравнению с их неочищенными версиями.

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

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

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

Возможно ли это вообще?

Обновление:

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

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

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

enter image description here

Author: Ferdy, 2012-11-30

2 answers

Рассмотрите возможность сохранения профиля 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, но, по крайней мере, цвета останутся нетронутыми.

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

 23
Author: Robbert, 2015-05-24 08:06:56

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

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

 1
Author: oucil, 2012-12-13 22:12:09