PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, September 18, 2022

[FIXED] How to remove exif from a JPG without losing image quality?

 September 18, 2022     imagick, php, thumbnails     No comments   

Issue

I have a PHP photo sharing application in which user-uploaded images are resized into various thumb formats using ImageMagick.

As a seemingly "smart" way to save on file size, I am stripping exif info from these thumbs as follow:

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

This works. It does remove the EXIF info, where a thumbs of 30KB saves 12KB and becomes 18KB. A significant saving when showing many of such thumbs on a single page.

The problem however is that it works a little too well. The resulting images seem to lose a lot of color information and look "flat" compared to their non-stripped versions.

Based on my research so far, my theory is that one or both of the following is true:

  • Imagick throws away essential color profile information as part of the stripping process
  • Imagick recompresses the image upon saving it, losing quality

Regardless of the cause of the problem, I'm looking for a way to remove EXIF information in such a way that it does not affect the image quality or color itself.

Is this even possible?

Update:

Based on Gerald Schneider's answer, I tried enforcing the quality setting to 100% prior to "stripping" the image:

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

Unfortunately, the problem remains. Below is example output where despite setting the quality to 100%, images are still flattened.

enter image description here


Solution

Consider keeping the ICC profile (which causes richer colors) while removing all other EXIF data:

  1. Extract the ICC profile
  2. Strip EXIF data and image profile
  3. Add the ICC profile back

In PHP + imagick:

$profiles = $img->getImageProfiles("icc", true);

$img->stripImage();

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

(Important note: using the ImageMagick 3.1.0 beta, the result I got from getImageProfiles() was slightly different from the documentation. I'd advise playing around with the parameters until you get an associative array with the actual profile(s).)

For command line ImageMagick:

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

Images will get recompressed of course if you use ImageMagick, but at least colors stay intact.

Hope this helps.



Answered By - Robbert
Answer Checked By - David Marino (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing