Как удалить exif из JPG без потери качества изображения?
У меня есть приложение для обмена фотографиями PHP, в котором пользовательские изображения изменяются в различные форматы большого пальца с помощью ImageMagick.
Как кажущийся "умный" способ сохранить размер файла, я удаляю exif-информацию из этих больших пальцев следующим образом:
$imagick = new Imagick($image);
$imagick->stripImage();
$imagick->writeImage($image);
Это работает. Он удаляет информацию EXIF, где превью 30 КБ экономит 12 КБ и становится 18 КБ. Значительная экономия при отображении многих таких больших пальцев на одной странице.
Однако проблема заключается в том, что она работает слишком хорошо. Полученные изображения, похоже, теряют много информации о цвете и выглядят "плоскими" по сравнению с их не разделенными версиями.
Основываясь на моих исследованиях до сих пор, моя теория заключается в том, что верно одно или оба из следующих утверждений:
- Imagick выбрасывает важную информацию о цветовом профиле как часть процесса зачистки.
- Imagick повторно сжимает изображение при сохранении его, теряя качество
Независимо от причины проблемы, я ищу способ удалить информацию EXIF таким образом, чтобы она не влияла на качество изображения или цвет.
Возможно ли это?
Update:
Основываясь на ответе Джеральда Шнайдера, я попытался применить настройку качества до 100% до "снятия" изображения:
$imagick = new Imagick($image);
$imagick->setCompression(imagick::COMPRESSION_JPEG);
$imagick->setCompressionQuality(100);
$imagick->stripImage();
$imagick->writeImage($image);
К сожалению, проблема остается. Ниже приведен пример вывода, который, несмотря на то, что качество 100%, изображения все еще сплющены.
![enter image description here]()
Ответы
Ответ 1
Рассмотрите возможность сохранения профиля ICC (который вызывает более насыщенные цвета) при удалении всех других данных EXIF:
- Извлечь профиль ICC
- Данные и профиль разделителя EXIF
- Добавить профиль 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, но по крайней мере цвета остаются нетронутыми.
Надеюсь, что это поможет.
Ответ 2
Сделав аналогичные изменения в типах MIME в заголовках файлов, которые были неправильно сохранены, я предлагаю вам проверить длину данных EXIF с помощью стандартных инструментов, а затем "Zero" данные вручную, используя многобайтовые строковые функции.
EXIF может быть не более 64 КБ в файле JPEG, но я не уверен, если он будет 64 КБ, поэтому я бы начал с этого.