8

私たちのサーバーは、で保存されたすべてのファイルに EXIF データを保存していますimagejpeg()。私の知る限り、これはデフォルトの動作ではありません(または、私が読んだ限りでは可能です)。しかし、それ発生しており、FileDateTime情報が含まれている (およびtime保存を使用している) ため、アップロード/承認システムの機能が壊れています (常に異なるmd5_file()ため、まったく同じ画像に対して異なる値を返しますFileDateTime)。

imagejpeg()デフォルトで画像の EXIF データを保存しないようにする方法はありますか?

サーバー情報

  • CentOS5
  • Parallels Plesk パネル 10.4.4
  • GD版:同梱(2.0.34対応)
  • PHP5.3

コード

<?php
public function upload_book_cover($book, $cover, $filename = NULL, $approved = NULL){
    global $c_consummo, $user;
    $approved = bool($approved, true, true);
    if(filesize($cover)>5242880){
        return false; // Too large;
    }
    $max_width = 450;
    $cover_info = getimagesize($cover);
    if(!$this->is_valid_book_cover_type($cover_info['mime'])){
        return false; // Invalid image type
    }
    $width = $cover_info[0];
    $height = $cover_info[1];
    if($width<200){
        return false; // Too small
    } elseif($width>1500){
        return false; // Too wide
    }
    $original_cover = false;
    switch($cover_info[2]){
        case IMAGETYPE_GIF:
            $original_cover = imagecreatefromgif($cover);
            break;
        case IMAGETYPE_JPEG:
            $original_cover = imagecreatefromjpeg($cover);
            break;
        case IMAGETYPE_PNG:
            $original_cover = imagecreatefrompng($cover);
            break;
        case IMAGETYPE_BMP:
            $original_cover = imagecreatefrombmp($cover);
            break;
    }
    if(!$original_cover){
        return false; // Unsupported type
    }
    if($width>$max_width){
        $new_width = $max_width;
    } else {
        $new_width = $width;
    }
    $new_height = round($height*($new_width/$width));
    $new_cover = imagecreatetruecolor($new_width, $new_height);
    if(!$new_cover){
        return false; // Could not create true color image
    }
    if(!imagecopyresampled($new_cover, $original_cover, 0, 0, 0, 0, $new_width, $new_height, $width, $height)){
        return false; // Could not copy image
    }
    if(!imagejpeg($new_cover, $cover, 100)){
        return false; // Image could not be saved to tmp file
        // This is adding *new* EXIF data to images by itself
    }
    $file_hash = md5_file($cover);
    $duplicate_book_cover = $this->find_duplicate_book_cover($book, $file_hash);
    if($duplicate_book_cover){
        return $duplicate_book_cover;
    }
    $file_id = $c_consummo->upload_file($cover, $filename);
    ...
}
4

10 に答える 10

4

EXIFデータが書き込まれている理由がわからないため、次のようにすると、データを削除するのに役立つ場合があります。

1つの提案は、サーバー上でコマンドとして何かを実行することです-インストールが必要です:http://hacktux.com/read/remove/exif-次に、PHPからEXECを実行します。

ImageMagickもインストールされている場合は、ImageMagickを使用するソリューションもここに投稿されています(またはインストールする場合:PHPを使用してJPGからEXIFデータを削除します(ただし、色に関する警告に注意してください)

それ以外の場合、他の提案は上記のとおりです。EXIT拡張機能をオフにしてみてください。

彼らが助けてくれないなら申し訳ありませんが、あなたは何か提案を求めました。

于 2012-05-11T11:49:57.997 に答える
4

ここでいくつかのことを試したようですが、もう 1 つ試してみましょう。アプリケーションに EXIF 情報が必要ですか? そうでない場合は、EXIF のサポートを削除して、それが完全に削除されるかどうかを確認してください。

削除されない場合は、関数が既存の写真からそれを読み取ってから、書き込まれたファイルにやみくもに含めている可能性があります。プロセスの各ステップで EXIF 情報を出力することで、確実に知ることができます。

于 2012-05-11T03:58:22.807 に答える
2

これを読んでください、多分それは役立つでしょう:

http://www.php.net/manual/en/function.imagecreatefromjpeg.php#65656

この:

http://www.sentex.net/~mwandel/jhead/usage.html

于 2012-05-14T15:17:58.770 に答える
2

どうやら 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);
...
于 2012-05-16T17:08:04.783 に答える
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 行ごとに 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);

私はこれのいくつかがうまくいくことを願っています(私は今それをテストすることができないので)、または少なくともあなたがあなたのために働く方法を見つけるのを助けるでしょう:)

于 2012-05-16T13:21:29.617 に答える
2

最初に を に変換してjpegから、 を に変換できます。そうすることで、EXIFデータを破壊することになると私は理解しています。これはハックですが、うまくいくはずです。gifgifjpeg

于 2012-05-09T16:51:55.743 に答える
0

PHPはでコンパイルする必要があります--enable-exif

このオプションを指定せずにPHPを再コンパイルして、グローバルにEXIF機能を無効にしてみてください。

于 2012-05-16T14:17:22.143 に答える
0

$res = imagecreatefromjpeg($filename)画像をロードしてimagejpeg($res, $filename, QUALITY)から再レンダリングします。

imagemagick も使用できます。

$img = new Imagick($image);
    $img->stripImage();
    $img->writeImage($image);
    $img->clear();
    $img->destroy();
于 2012-05-09T23:08:52.057 に答える
0

imagecreatefromjpegで作成したイメージを使用して、新しく作成したイメージimagejpegに置き換えることができます。

于 2012-05-09T22:53:47.983 に答える