4

複数の画像をアップロードできる小さな CMS をコーディングしています。これらの画像は、imagemagick を使用して3 つのバージョン (大、中、およびサムネイル サイズ)に変換されます。

問題は、imagemagick が (アップロードされた) 4 つの写真の 3 つのバージョンを作成するのに 5 分かかることです。

imagemagick コマンドの部分は次のとおりです。

foreach($upIMGS as $key => $filename){
    list($width, $height) = getimagesize($path.$filename);
    if ($width > $height) $size = "x96";
    else $size = "96x";

    exec(P_IMAGEMAGICK." ".$path.$filename." -resize $size -gravity center -crop 96x96+0+0 +repage ".$path."th-".$filename);
    exec(P_IMAGEMAGICK." ".$path.$filename." -resize 320x320 ".$path."hl-".$filename);
    exec(P_IMAGEMAGICK." ".$path.$filename." -resize 514x ".$path."fl-".$filename);

    unlink($path.$filename);
}

[$upIMGS は、最近アップロードされた画像のすべてのファイル名を含む配列です]

つまり..動作しますが、遅すぎて5分後にサーバーからエラーが発生します。一部のファイルは生成され、一部は生成されません...

ヒントを頂ければとても助かります。

4

4 に答える 4

9

最近同じ問題に遭遇しましたが、元の 2592x1944 から 300xbestFit または bestFitx300 にサイズ変更するために、画像を 1 回だけ通過していました。

コマンド ラインの代わりに PHP クラスの imagick を使用していますが、私の場合は -scale または scaleImage に変更することで時間を半分に短縮できました。これが私のテストコードのスニペットです。

while ($images = readdir($handle)) {
    // check to see if the first or second character is a '.' or '..', 
    // if so then remove from list
    if (substr($images,0,1) != '.') {
        //Check files to see if there extensions match any of the following image extensions. 
        // GLOB_BRACE looks for all glob criteria within the {braces}
        $images = glob($dir."{*.gif,*.jpg,*.png,*.jpeg}", GLOB_BRACE);
        // the glob function gives us an array of images
        $i = 0;
        foreach ($images as $image) {
            // parse the data given and remove the images/ $dir, 
            // imagemagick will not take paths, only image names.
            $i++;
            list ($dir, $image) = split('[/]', $image);
            echo $i, " ", $image, "<br />";

            $magick = new Imagick($dir."/".$image);
            $imageprops = $magick->getImageGeometry();

            if ($imageprops['width'] <= 300 && $imageprops['height'] <= 300) {
                // don't upscale
            } else {

                // 29 Images at 2592x1944 takes 11.555036068 seconds -> 
                // output size = 300 x 255
                $magick->scaleImage(300,300, true);

                // 29 Images at 2592x1944 takes 23.3927891254 seconds -> 
                // output size = 300 x 255
                //$magick->resizeImage(300,300, imagick::FILTER_LANCZOS, 0.9, true);
                $magick->writeImage("thumb_".$image);

            }
        }
    }
}

2592x1944 で 29 枚の画像を処理していますが、23.3927891254 秒から 11.555036068 秒になりました。これが役立つことを願っています。

編集:

上で言ったことに加えて、ImageMagick v6 Examples -- API & Scriptingで役立つかもしれない以下に出くわしました:

  • 「シェルスクリプトは本質的に遅いです。解釈され、複数のステップとディスクへの余分なファイル処理が必要です。これはもちろん、新しい IM v6 オプション処理のおかげで改善され、単一のコマンドで多数の画像処理操作を実行できます。 . それでも、1 つのコマンドですべてを実行できることはめったにないconvertため、目的を達成するために複数のコマンドを使用する必要があることがよくあります。

  • 「大量の画像または多数の画像を読み取る場合は、読み取りモディファイアを使用してサイズ変更またはトリミングすることをお勧めします。IM は完全な画像を読み取らないため、メモリ要件が軽減されます。」

  • 「ImageMagick を Apache モジュールとして呼び出すと、再ロードを何度も行う必要がなく、パーツが一度ロードされ、複数回使用できるようになるため、起動時間も短縮されます。これは、永続的な「デーモン」IM プロセスを実行しています。」

于 2012-04-18T13:28:18.187 に答える
3

この例は、メインの画像をメモリにロードし、それを処理して他の画像を作成するのに役立つ場合があります。

$cmd = " input.jpg \( -clone 0 -thumbnail x480 -write 480_wide.jpg +delete \)". 
" \( -clone 0 -thumbnail x250 -write 250_wide.jpg +delete \) ". 
" \( -clone 0 -thumbnail x100 -write 100_wide.jpg +delete \) -thumbnail 64x64! null: ";
exec("convert $cmd 64_square.jpg ");

これにより、4 つの異なるサイズの画像が作成されます。

于 2012-04-21T07:57:01.177 に答える
2

何を待つ?アップロードされた3枚の写真から12枚の写真を生成するのに5分かかることはありません。

コードの残りの部分は表示されませんが、getimagesizeパスが$path。$filenameであるのに、P_UPLOADS。$valueのリンクが解除されているのはなぜですか。それらが異なる理由はありますか?とにかく$valueはどこから来るのでしょうか、foreach()ループでは定義されていません。たぶん、スクリプトがハングする原因となるバグがあるだけかもしれません。私はImageMagickを使用しましたが(exec()ではなく、実際のクラスで)、非常に高速でした。

foreach loop()で診断を実行しましたか?ミリ秒単位の出力と同様に、これらのexec()コマンドのそれぞれを実行するのに必要です。

于 2012-04-17T11:03:03.063 に答える
0

ちょっとしたコツは、最初に最大の画像を作成してから、オリジナルではなく、この画像から後続の画像を作成することです。

しかし、とにかく5分はたった12枚の画像には長すぎるようです。
あなたはいくつかの調査をしなければなりません。

  • ソースが比較的小さい場合(たとえば1024x768)、サイズ変更にはかなりの時間がかかりますか?
  • シェルから直接呼び出されるのと同じ時間がかかりますか?

遅延が避けられない場合は、サイズ変更機能を専用サーバーに移動し、それらをキューに入れて、単純なAJAXスニペットでプロセスを確認することをお勧めします。

于 2012-04-17T11:03:47.967 に答える