阻止imagejpeg()保存图像的EXIF数据(spec.FileDateTime)

时间:2012-04-30 17:43:22

标签: php gd exif

我们的服务器正在将EXIF数据保存到使用imagejpeg()保存的每个文件中。据我所知,这是的默认行为(甚至可能,从我读过的内容)。但是, 正在发生,并且由于包含FileDateTime信息(并使用保存的time),它在我们的上传/审批系统中打破了功能({由于md5_file()始终不同,{1}}会为完全相同的图片返回不同的值。

默认情况下,是否有办法阻止FileDateTime保存图片的EXIF数据?

服务器信息

  • CentOS 5
  • Parallels Plesk Panel 10.4.4
  • GD版本:捆绑(2.0.34兼容)
  • PHP 5.3

代码

imagejpeg()

10 个答案:

答案 0 :(得分:4)

看起来你已经尝试了几件事,但我们再试一次。 您是否需要在您的应用程序中使用EXIF信息? 如果没有,请取出对EXIF的支持,看看是否完全删除它。

如果它没有删除它,那么函数可能是从现有照片中读取它,然后盲目地将它包含在写入的文件中。 您可以通过在流程的每个步骤打印出EXIF信息来确定。

答案 1 :(得分:4)

不知道为什么要写EXIF数据 - 所以以下内容可以帮助您删除它。

一个建议是在服务器上运行某些命令 - 它需要一些安装:http://hacktux.com/read/remove/exif - 然后从PHP运行EXEC。

此处还发布了使用ImageMagick的解决方案,如果您还安装了它(或者安装了它:Remove EXIF data from JPG using PHP(但请注意有关颜色的警告)

否则,其他建议如上所述,请尝试关闭EXIT扩展名。

很抱歉,如果他们没有帮助,但你确实要求任何建议。

答案 2 :(得分:2)

您可以先将jpeg转换为gif,然后将gif转换回jpeg。这样做,我的理解是你会破坏EXIF数据。这是一个黑客,但它应该工作。

答案 3 :(得分:2)

答案 4 :(得分:2)

唯一让人想到的是,您可以忽略EXIF数据,只是从其他东西中获取哈希值?我的建议是尝试散列原始输出而不保存到文件(这里以gif格式输出 - 它为性能提供较小的8位图像 - 输出缓冲区并散列缓冲区内容)

if(!imagecopyresampled(...)) {...}
ob_start();
imagegif($new_cover);
$file_hash = md5(ob_get_contents());
ob_end_clean();
if(!imagejpeg($new_cover, $cover, 100)) {...}

或者你可以构建一个只包含像素信息和散列的字符串(这里通过访问每个像素并将其值附加到字符串,反过来提高性能)

$pixels = '';
for($x=$new_width-1; $x>=0; $x--) {
  for($y=$new_height-1; $y>=0; $y--) {
    $pixels .= imagecolorat($new_cover, $x, $y);
  }
}
$file_hash = md5($pixels);

为了提高性能,您还可以选择仅从图像中采样,因为这应该可以正常工作,甚至更好(这里每隔5行采样一次)

$pixels = '';
for($x=$new_width-1; $x>=0; $x-=5) {
  for($y=$new_height-1; $y>=0; $y-=5) {
    $pixels .= imagecolorat($new_cover, $x, $y);
  }
}
$file_hash = md5($pixels);

我希望其中一些可行(因为我现在无法测试)或者至少会帮助您找到适合您的方式:)

答案 5 :(得分:2)

显然,GD不喜欢输入/输出文件的路径相同,但the credit不是我的。要修复,请使用新的(tmp)文件将新创建的图像保存到:

<?php
...
if(!imagecopyresampled($new_cover, $original_cover, 0, 0, 0, 0, $new_width, $new_height, $width, $height)){
 return false; // Could not copy image
}
// Create a tmp file.
$cover_new = tempnam('/tmp', 'cover-');
// Use $cover_new instead of $cover
if(!imagejpeg($new_cover, $cover_new, 100)){
 return false; // Image could not be saved to tmp file
}
// Use $cover_new instead of $cover
$file_hash = md5_file($cover_new);
$duplicate_book_cover = $this->find_duplicate_book_cover($book, $file_hash);
if($duplicate_book_cover){
 return $duplicate_book_cover;
}
// Use $cover_new instead of $cover
$file_id = $c_consummo->upload_file($cover_new, $filename);
...

答案 6 :(得分:1)

这有点像黑客,但它会起作用,只需在switch()声明后执行此操作:

$original_cover = imagerotate($original_cover,360,0);

GD将删除任何EXIF数据,因为它不支持它。

答案 7 :(得分:0)

您可以尝试在使用imagecreatefromjpeg创建的图像上使用imagejpeg并替换为新创建的图像。

答案 8 :(得分:0)

$res = imagecreatefromjpeg($filename)加载图片,然后imagejpeg($res, $filename, QUALITY)重新加载图片。

您也可以使用imagemagick:

$img = new Imagick($image);
    $img->stripImage();
    $img->writeImage($image);
    $img->clear();
    $img->destroy();

答案 9 :(得分:0)

  

您的PHP必须使用--enable-exif编译。

尝试通过重新编译没有此选项的PHP来禁用全局EXIF功能。