0

私は動的なサムネイル スクリプトを Web のあちこちで見つけて、少し調整しました。私が追加したことの 1 つは、キャッシング メカニズムでした。新しいサムネールが生成されるたびにディスクに保存され、同じサムネイル (すべて同じオプションを使用) が再度要求された場合は、ディスク コピーが使用されます。

スニペット:

  // name of cached file
  $thumb_file = $_SERVER['DOCUMENT_ROOT'].'/thumbs/cache/'.
                str_replace('/', '_', $_REQUEST['p']).
                ".{$def_width}x{$def_height}".
                ($clamp ? '_'.implode('x',$clamp) : '').
                ($make_png?'.png':'.jpg');

  // get it from cache if it's there
  if ($use_cache && file_exists($thumb_file)) {
    Header("Content-type: image/".($make_png?'png':'jpeg'));

    // this part seems really slow

    $fp=fopen($thumb_file, "rb");
    while (!feof($fp)) print fread($fp, 4096);

    exit();
  }

ただし、printing の結果はfread非常に遅いようで、(ごくまれに) 画像が完全に読み込まれないことがあります。

では、どうすればこれを高速化できますか?ブラウザを画像にリダイレクトする代わりに画像にリダイレクトするfread必要がありますか、それとも別のオプションがありますか?

念のため、以下に完全な PHP スクリプトを含めます。

<?php

  $use_cache = $_REQUEST['nc'] ? false : true;
  // $use_cache = false;

  $upfile = $_SERVER['DOCUMENT_ROOT'] .'/'. $_REQUEST['p'];
  $def_width  = $_REQUEST["w"];
  $def_height = $_REQUEST["h"];
  $clamp = $_REQUEST['c'] ? explode("x",$_REQUEST['c']) : null;
  $make_png = $_REQUEST['png'];

  if (!file_exists($upfile)) {
    die();  // $upfile = "nophoto.jpg";
  }

  if (!"{$def_width}{$def_height}") {
    $def_width = $def_height = '100';
  }

  // name of cached file
  $thumb_file = $_SERVER['DOCUMENT_ROOT'].'/thumbs/cache/'.
                str_replace('/', '_', $_REQUEST['p']).
                ".{$def_width}x{$def_height}".
                ($clamp ? '_'.implode('x',$clamp) : '').
                ($make_png?'.png':'.jpg');

  // get it from cache if it's there
  if ($use_cache && file_exists($thumb_file)) {
    Header("Content-type: image/".($make_png?'png':'jpeg'));
    $fp=fopen($thumb_file, "rb");
    while (!feof($fp)) print fread($fp, 4096);
    exit();
  }

  $ext = strtolower(substr($upfile, -3));

  ini_set('memory_limit', '64M');

  if ($ext=="gif") 
    $src = @ImageCreateFromGif ($upfile);
  else if ($ext=="jpg") 
    $src = @ImageCreateFromJpeg($upfile);
  else if ($ext=="png") 
    $src = @ImageCreateFromPng($upfile);

  $size = GetImageSize($upfile); 
  $width = $size[0];
  $height = $size[1];

  $long_side = $def_width;
  if ($def_width < $def_height) $long_side = $def_height;

  if (!$def_width) {
    $factor_h = $height / $def_height;
    $def_width = $width / $factor_h;
  }
  if (!$def_height) {
    $factor_w = $width / $def_width;
    $def_height = $height / $factor_w;
  }
  $factor_w = $width / $def_width;
  $factor_h = $height / $def_height;

  if ($factor_w > $factor_h) {
    $new_height = floor($def_height * $factor_h);
    $new_width = floor($def_width  * $factor_h);
  } else {
    $new_height = floor($def_height * $factor_w);
    $new_width = floor($def_width  * $factor_w);
  }

  if ((!$clamp[0])&&$clamp[0]!=='0') $clamp[0] = 50;
  if ((!$clamp[1])&&$clamp[1]!=='0') $clamp[1] = 50;

  $src_x = ceil(($width  - $new_width)  * ($clamp[0] / 100));
  $src_y = ceil(($height - $new_height) * ($clamp[1] / 100));

  $dst = ImageCreateTrueColor($def_width, $def_height);

  @ImageCopyResampled($dst, $src, 0, 0, $src_x, $src_y, 
                      $def_width, $def_height, $new_width, $new_height);

  Header("Content-type: image/".($make_png?'png':'jpeg'));

  if ($make_png) {
    ImagePng($dst);
    if ($use_cache) { 
      ImagePng($dst, $thumb_file); 
    }
  } else {
    ImageJpeg($dst, null, 95);
    if ($use_cache) { 
      ImageJpeg($dst, $thumb_file, 95); 
    }
  }

  @ImageDestroy($src);
  @ImageDestroy($dst);

?>
4

4 に答える 4

1

関数readfileはより高速にする必要があります。

PHP を Apache モジュールとして使用している場合は、virtual.

于 2010-08-15T02:13:45.903 に答える
0

Web サーバーがサポートしている場合は、X-Sendfile速度が向上する可能性があります。

于 2010-08-15T05:59:23.167 に答える
0

特定の数値に関して、「思われる」および「非常に遅い」を定義してください。
それ以外の場合は、「おおよそ何かを得ることができるようです」という同じ用語でのみ回答が存在する可能性があります。

「どうすればスピードアップできますか」と尋ねている人は、まず次の質問に答えてください。

  • スピードアップしたい特定の操作
  • 現時点でどの程度の時間がかかるか。
  • どのくらいの時間が私に合っていますか。

私自身の完璧ではないテストによると、PHP 経由での画像の提供は、Web サーバー自体経由よりも 2 倍遅くなります。「非常に遅い」とは言えません。
そのため、実行速度が「非常に遅い」場合は、他の理由が考えられます。このキャッシュメカニズムのように、なんらかのミスによりまったく機能していません。か何か。誰かが助ける前に、いくつかのプロファイリングデバッグ必要です。

特に「これは答えじゃない!」と訝しむ方には。(答えがそれだけをカウントするというばかげた仮定のため、それは直接的で肯定的です)、OPが学ぶためのリンクは次のとおりです:
http
://shiftingpixel.com/2008/03/03/smart-image-resizer/ 同じその場でサムネイル作成スクリプトを実行しますが、「変更されていません」HTTP キャッシュ実装を使用します。

于 2010-08-15T06:04:43.840 に答える
0

PHP5 に移行します。
PHP 4 にはいくつかのバグがあり、あらゆる形態の fread の速度が低下し、メモリ リークが発生しました。あなたの説明に基づいて、それはあなたが反対していることのように聞こえます。

アップグレード、できれば少なくとも 5.3+ に

于 2011-01-30T21:11:02.820 に答える