9

ユーザーがアバタータイプの画像をさまざまな形式 (少なくとも GIF、JPEG、および PNG ) でアップロードできるようにしたいのですが、それらをすべてPNG データベース BLOBとして保存します。画像がピクセル単位で大きすぎる場合は、DB 挿入の前にサイズを変更したいと考えています。

GD を使用してサイズ変更と PNG 変換を行う最良の方法は何ですか?

編集:悲しいことに、私が使用する必要があるサーバーではGDのみが利用可能であり、 ImageMagickは利用できません。

4

9 に答える 9

24
<?php                                              
/*
Resizes an image and converts it to PNG returning the PNG data as a string
*/
function imageToPng($srcFile, $maxSize = 100) {  
    list($width_orig, $height_orig, $type) = getimagesize($srcFile);        

    // Get the aspect ratio
    $ratio_orig = $width_orig / $height_orig;

    $width  = $maxSize; 
    $height = $maxSize;

    // resize to height (orig is portrait) 
    if ($ratio_orig < 1) {
        $width = $height * $ratio_orig;
    } 
    // resize to width (orig is landscape)
    else {
        $height = $width / $ratio_orig;
    }

    // Temporarily increase the memory limit to allow for larger images
    ini_set('memory_limit', '32M'); 

    switch ($type) 
    {
        case IMAGETYPE_GIF: 
            $image = imagecreatefromgif($srcFile); 
            break;   
        case IMAGETYPE_JPEG:  
            $image = imagecreatefromjpeg($srcFile); 
            break;   
        case IMAGETYPE_PNG:  
            $image = imagecreatefrompng($srcFile);
            break; 
        default:
            throw new Exception('Unrecognized image type ' . $type);
    }

    // create a new blank image
    $newImage = imagecreatetruecolor($width, $height);

    // Copy the old image to the new image
    imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

    // Output to a temp file
    $destFile = tempnam();
    imagepng($newImage, $destFile);  

    // Free memory                           
    imagedestroy($newImage);

    if ( is_file($destFile) ) {
        $f = fopen($destFile, 'rb');   
        $data = fread($f);       
        fclose($f);

        // Remove the tempfile
        unlink($destFile);    
        return $data;
    }

    throw new Exception('Image conversion failed.');
}
于 2008-08-22T13:49:01.267 に答える
6

プロセスの手順は次のようになります。

  1. ファイルタイプを確認する
  2. imagecreatefrom*を使用して、サポートされているファイル タイプのイメージを GD にロードします。
  3. imagecopyresizeまたはimagecopyresampledを使用したサイズ変更
  4. imagepng($handle, 'filename.png', $quality, $filters)を使用して画像を保存します。

ImageMagick は高速で、より優れた画像を生成し、構成可能であり、最終的に (IMO) コーディングがはるかに簡単です。

@ceejayoz新しいGDを待つだけです-それはMySQLiのようなOOPであり、実際には悪くありません:)

于 2008-08-22T13:14:56.373 に答える
3

サーバーに ImageMagick がありませんか?

私はあなたが PHP を使用していると思います (質問は PHP でタグ付けされています)。私が使用しているホスティング会社では、phpinfo() によると、ImageMagick 拡張機能が有効になっていません。

しかし、彼らに尋ねたところ、ここに PHP コードから利用できる ImageMagick プログラムのリストがあるとのことでした。簡単に言うと、PHP には IM インターフェースはありませんが、IM プログラムを PHP から直接呼び出すことができます。

同じ選択肢があることを願っています。

そして、私は強く同意します-データベースに画像を保存することはお勧めできません。

于 2008-08-22T13:23:32.793 に答える
3

おそらく、次のようなものです。


<?php
   //Input file
   $file = "myImage.png";
   $img = ImageCreateFromPNG($file);

   //Dimensions
   $width = imagesx($img);
   $height = imagesy($img);
   $max_width = 300;
   $max_height = 300;
   $percentage = 1;

   //Image scaling calculations
   if ( $width > $max_width ) { 
      $percentage = ($height / ($width / $max_width)) > $max_height ?
           $height / $max_height :
           $width / $max_width;
   }
   elseif ( $height > $max_height) {
      $percentage = ($width / ($height / $max_height)) > $max_width ? 
           $width / $max_width :
           $height / $max_height;
   }
   $new_width = $width / $percentage;
   $new_height = $height / $percentage;

   //scaled image
   $out = imagecreatetruecolor($new_width, $new_height);
   imagecopyresampled($out, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

   //output image
   imagepng($out);
?>

私はコードをテストしていないので、構文エラーがあるかもしれませんが、それがどのように行われるかについて公正なプレゼンテーションを提供するはずです. また、PNGファイルを想定しています。ファイルの種類を判別するために、ある種の switch ステートメントが必要になる場合があります。

于 2008-08-22T13:26:06.937 に答える
3

gdlib を使用する場合は、gdlib 2 以降を使用してください。これには imagecopyresampled() という関数があり、サイズ変更中にピクセルを補間して見栄えを良くします。

また、データベースに画像を保存することは悪い形式であるとネット上で常に聞いています。

  • ディスクよりもアクセスが遅い
  • サーバーは、単にファイルを提供するのではなく、スクリプトを実行して画像を取得する必要があります
  • あなたのスクリプトは、Web サーバーが処理していた多くのものを処理するようになりました。
    • 適切な Content-Type ヘッダーの設定
    • 適切なキャッシング/タイムアウト/E-tag ヘッダーを設定して、クライアントが画像を適切にキャッシュできるようにします。これを適切に行わないと、画像提供スクリプトがすべてのリクエストでヒットし、サーバーの負荷がさらに増加し​​ます。

唯一の利点は、データベースと画像ファイルの同期を維持する必要がないことです。私はまだそれに対してお勧めします。

于 2008-08-22T13:07:29.480 に答える
1

GDは絶対に必要ですか?ImageMagickは高速で、より優れた画像を生成し、構成可能であり、最終的に (IMO) コーディングがはるかに簡単です。

于 2008-08-22T12:58:51.403 に答える
0

この記事は、あなたが望むものに合っているようです。保存する imagejpeg() 関数を imagepng() に変更し、ファイルをページに出力するのではなく文字列に保存する必要がありますが、それ以外は既存のコードに簡単にコピー/貼り付けできます。

于 2008-08-22T12:57:24.480 に答える
0

このページは良い出発点だと思います。imagecreatefrom(jpeg/gif/png) を使用して、画像をリサイズおよび変換し、ブラウザに出力します。ブラウザーを出力する代わりに、DB 内の BLOB に出力することができ、コードを何度も書き直す必要はありません。

于 2008-08-22T12:58:54.507 に答える
0

phpThumbは、一見の価値がある高レベルの抽象化です。

于 2008-09-04T14:12:13.727 に答える