如何在不丢失图像质量的情况下从JPG中删除exif?

时间:2012-11-30 13:16:04

标签: php thumbnails imagick

我有一个PHP照片共享应用程序,其中使用ImageMagick将用户上传的图像调整为各种拇指格式。

作为一种节省文件大小的看似“智能”方式,我正在从这些拇指中删除exif信息,如下所示:

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

这很有效。它确实删除了EXIF信息,其中30KB的大拇指节省12KB并变为18KB。当在一个页面上显示许多这样的拇指时,显着节省了。

然而问题是它的效果有点太好了。由此产生的图像似乎丢失了大量的颜色信息,并且与非剥离版本相比看起来“平坦”。

根据我迄今为止的研究,我的理论是以下一个或两个都是正确的:

  • Imagick将基本颜色配置文件信息作为剥离过程的一部分丢弃
  • Imagick在保存图像时重新压缩图像,质量下降

无论问题的原因是什么,我都在寻找一种方法来删除EXIF信息,使其不会影响图像质量或颜色本身。

这甚至可能吗?

更新

根据Gerald Schneider的回答,我尝试在“剥离”图像之前将质量设置强制设置为100%:

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

不幸的是,问题仍然存在。下面是示例输出,尽管将质量设置为100%,图像仍然是平坦的。

enter image description here

3 个答案:

答案 0 :(得分:26)

考虑保留ICC配置文件(导致更丰富的颜色),同时删除所有其他EXIF数据:

  1. 提取ICC配置文件
  2. 剥离EXIF数据和图像配置文件
  3. 添加ICC个人资料
  4. 在PHP + imagick中:

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

    (重要说明:使用ImageMagick 3.1.0测试版,我从getImageProfiles()获得的结果与documentation略有不同。我建议您使用参数,直到获得关联具有实际配置文件的数组。)

    对于命令行ImageMagick:

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

    如果使用ImageMagick,图像会被重新压缩,但至少颜色保持不变。

    希望这有帮助。

答案 1 :(得分:1)

对错误存储的文件头中的MIME类型进行了类似的更改,我建议您通过标准工具验证EXIF数据的长度,然后使用多字节字符串函数手动“清零”数据。

EXIF在JPEG文件中最多只能是64KB,但如果它是64KB,我不是正面的,所以我会从这开始。

答案 2 :(得分:0)

GIMP(另一个开源图像编辑器)还允许在不降低图像/图片质量的情况下删除 EXIF、IPTC、XMP、缩略图、ICC(颜色配置文件)等元数据。

在 GIMP 中打开图像后,选择“导出”/“导出为”等选项,然后选择/取消选择要删除/保留的元数据。

要保持原始图像质量,您必须选择(打勾)选项“使用原始图像的质量设置”,该选项显示在顶部的“质量”滑动条下方。

我通常喜欢选择 ICC(保存颜色配置文件元数据)选项,以保持良好的色彩质量,并带有彩色照片。
其他选项(保存 EXIF、保存 IPTC、保存 XMP、保存缩略图等)我通常不选择。

更多信息:here