Php 防止imagejpeg()保存图像的EXIF数据(规范FileDateTime)

Php 防止imagejpeg()保存图像的EXIF数据(规范FileDateTime),php,gd,exif,Php,Gd,Exif,我们的服务器正在将EXIF数据保存到使用imagejpeg()保存的每个文件中。据我所知,这不是默认的行为(或者从我所读到的内容来看,甚至不可能)。但是,它正在发生,并且由于包含了FileDateTime信息(并且使用save的time),它正在破坏我们上传/审批系统中的功能(md5_file()由于FileDateTime总是不同,因此会为完全相同的图像返回不同的值) 默认情况下,是否有方法防止imagejpeg()保存图像的EXIF数据 服务器信息 CentOS 5 平行普莱斯克面板10.

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

默认情况下,是否有方法防止
imagejpeg()
保存图像的EXIF数据

服务器信息
  • CentOS 5
  • 平行普莱斯克面板10.4.4
  • GD版本:捆绑(2.0.34兼容)
  • PHP5.3
代码
您可以先将
jpeg
转换为
gif
,然后将
gif
转换回
jpeg
。我的理解是,这样做会破坏EXIF数据。这是一个黑客程序,但应该可以使用。

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

$res=imagecreatefromjpeg($filename)
加载图像,然后
imagejpeg($res,$filename,QUALITY)
重新渲染

您也可以使用imagemagick:

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

看起来您在这里尝试了几种方法,但让我们再尝试一种。 您的应用程序中是否需要EXIF信息? 如果没有,让我们拿出对EXIF的支持,看看这是否完全消除了它

如果它没有删除它,那么可能函数正在从现有的照片中读取它,然后盲目地将它包含在写入的文件中。
您可以通过在流程的每个步骤打印出EXIF信息来确定,不知道为什么要写入EXIF数据,因此以下内容可能会帮助您删除它

一个建议是在服务器上以命令的形式运行一些东西-它需要一些安装:-然后从PHP运行throuhg EXEC

如果您也安装了ImageMagick(或cen安装了它),这里还发布了一个使用ImageMagick的解决方案:(但请注意有关颜色的警告)

否则,另一个建议如上所述,尝试关闭出口分机


如果他们不帮忙,很抱歉,但您确实征求了任何建议。

阅读此文章,也许会有帮助:

这是:


唯一让人想到的是,您可以忽略EXIF数据,而只是从其他数据中进行散列?我的建议是尝试对原始输出进行散列,而不保存到文件中(此处以gif格式输出,这会生成更小的8位图像,以提高性能)到输出缓冲区并对缓冲区内容进行散列)

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

为了提高性能,您还可以选择仅从图像中采样,因为这应该同样有效,甚至可能更好(此处每5行的每5个像素采样一次)


我希望其中的一些方法能起作用(因为我现在无法测试它),或者至少能帮助您找到适合您的方法:)

这是一个小技巧,但它会起作用,只需在您的
switch()
语句之后执行此操作:

$original_cover = imagerotate($original_cover,360,0);
GD将删除任何EXIF数据,因为它不支持它

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


尝试在不使用此选项的情况下通过重新编译PHP来禁用全局EXIF功能。

显然,GD不喜欢输入/输出文件的路径相同,但不是我的路径。要修复此问题,请使用新(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);
...

为了以防万一,我将尝试使用它,但问题不在于以前附加到图像的EXIF数据——服务器实际上正在将新的EXIF数据附加到图像(完全忽略旧的EXIF数据)。这真的很奇怪,似乎是特定于服务器的,但我不确定要更改哪些设置。转换为
gif
也会导致质量下降,因为它只有256色。我确实在每一步后打印了EXIF信息——每次刷新时都会用当前日期和时间更新它。不,我的应用程序中不需要(或不想要)EXIF信息——如何关闭对它的支持?也许从php.ini中删除扩展。正如AlixAxel在问题的评论中提到的,这是一个可变问题。谢谢你的建议!谢谢你的建议,我会浏览一下,看看其中是否有帮助!您可以对原始文件进行哈希处理。@AlixAxel,我不希望包含EXIF数据(在原始上载或新版本中),因为我不希望文件被认为是不同的,因为EXIF数据在某个地方发生了更改(而不更改图像本身)。散列的全部目的是避免在我们的服务器上存储同一个图像的多个版本。是的,我知道,但是因为你现在无法检查重复的图像,比较上传图像的散列会给你更好的机会。总之,奇怪的问题。祝你好运@AlixAxel,哦,是的,那将是最后的解决办法——我们希望它不会达到那个目的!谢谢!:)您是否可以尝试将所有出现的
$cover
(在
imagejpeg($new\u cover,$cover,100)
)替换为
$cover'。新建“
并查看问题是否仍然存在?抱歉,这不起作用!(我也不认为GD支持它,因此我感到困惑。)也许你需要对$new_cover和$cover这样做?也许值得一试。我想我在解释把它放在哪里时误解了你的问题。这太奇怪了!您有权访问服务器上ImageMagick的转换程序吗?我想那是你最好的选择。我知道!是的,我想这可能是我必须考虑的
$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);
$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);
$original_cover = imagerotate($original_cover,360,0);
<?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);
...