3

PHP GD ライブラリを使用して、画像のサイズ変更とトリミングのクラスを開発しました。最初のステップで画像の背景をトリミングし、2 番目のステップで画像を必要なサイズにスケーリングする (元の比率を維持する) ために、skibulks 画像トリム スクリプトを使用しました。

質問:関数imagecopyから新しいトリミングされた画像サイズを取得した後、最初のジョブを実行して、最初に新しいトリミングされたサイズで画像を再作成する必要がありますか (その後、再度サイズ変更します)? または、このジョブを下記のリサイズパーツとマージすることは可能ですか?$this->_trimBackground()imagecopyimagecopyresampled

私が知らない他の可能なパフォーマンスの改善はありますか? パフォーマンスに関するあらゆる提案を歓迎します。

機能 1:

/**
 * Resize image file
 * 
 * @param   string $filepath the image filepath
 * @param   integer $width the width to resize
 * @param   integer $height the height to resize
 * @return  (image blob|boolean status)
 * @throws  Asset_Model_Image_Exception
 */
private function _resizeImageByFilepathAndReturn($filepath, $width, $height) {

    list($imageWidth, $imageHeight, $imageType) = getimagesize($filepath);

   switch($imageType) {
    case IMAGETYPE_GIF:
            $gdImage = imagecreatefromgif($filepath);
            break;
      case IMAGETYPE_JPEG:
            $gdImage = imagecreatefromjpeg($filepath);
            break;
      case IMAGETYPE_PNG:
            $gdImage = imagecreatefrompng($filepath);
            break;
      default:
                return false;
   }

   if($box = $this->_trimBackground($gdImage)) {

    $gdTrimmed = imagecreatetruecolor($box['w'], $box['h']);
    imagecopy($gdTrimmed, $gdImage, 0, 0, $box['l'], $box['t'], $box['w'], $box['h']);

    $imageWidth = $box['w'];
    $imageHeight = $box['h'];
    $gdImage = $gdTrimmed;

    unset($gdTrimmed);

   }

   if($imageWidth <= $width && $imageHeight <= $height) {

    $fwidth = $imageWidth;
        $fheight = $imageHeight;

   } else {

        $wscale = $width / $imageWidth;
        $hscale = $height / $imageHeight;
        $scale = min($wscale, $hscale);
        $fwidth = $scale * $imageWidth;
        $fheight = $scale * $imageHeight;

   }

   $gdThumbnail = imagecreatetruecolor($width, $height);

   imagefill($gdThumbnail, 0, 0, 0x00FFFFFF);

   imagecopyresampled($gdThumbnail, $gdImage, ($width - $fwidth) / 2, ($height - $fheight) / 2, 0, 0, $fwidth, $fheight, $imageWidth, $imageHeight);

   ob_start();
   imagejpeg($gdThumbnail, null, 90);
   $image = ob_get_contents();
   ob_end_clean();

   imagedestroy($gdImage);
   imagedestroy($gdThumbnail);

   return $image;

}

機能 2:

/**
 * Trim image background
 * 
 * @param $gdImage image ressource
 */
private function _trimBackground($gdImage){

    $hex = imagecolorat($gdImage, 0,0);

    $width = imagesx($gdImage);
    $height = imagesy($gdImage);

    $bTop = 0;
    $bLft = 0;
    $bBtm = $height - 1;
    $bRt = $width - 1;

    for(; $bTop < $height; ++$bTop) {
        for($x = 0; $x < $width; ++$x) {
            if(imagecolorat($gdImage, $x, $bTop) != $hex) {
                break 2;
            }
        }
    }

    if($bTop == $height) {
        return false;
    }

    for(; $bBtm >= 0; --$bBtm) {
        for($x = 0; $x < $width; ++$x) {
            if(imagecolorat($gdImage, $x, $bBtm) != $hex) {
                break 2;
            }
        }
    }

    for(; $bLft < $width; ++$bLft) {
        for($y = $bTop; $y <= $bBtm; ++$y) {
            if(imagecolorat($gdImage, $bLft, $y) != $hex) {
                break 2;
            }
        }
    }

    for(; $bRt >= 0; --$bRt) {
        for($y = $bTop; $y <= $bBtm; ++$y) {
            if(imagecolorat($gdImage, $bRt, $y) != $hex) {
                break 2;
            }
        }
    }

    $bBtm++;
    $bRt++;

    return array('l' => $bLft, 't' => $bTop, 'r' => $bRt, 'b' => $bBtm, 'w' => $bRt - $bLft, 'h' => $bBtm - $bTop);

}
4

1 に答える 1

5

imagecopy() は $gdImage のセクションを $gdTrimmed にコピーし、数行後に $gdImage を $gdTrimmed で上書きします。

最初のイメージコピーを実行する必要は本当にありますか?

それはあなたが自問すべきことです。

imagedestroy()の代わりに関数を使用するとunset()、パフォーマンスが大幅に向上する場合があります。imagedestroy()に関する便利なコメントを次に示します。

イメージ変数を再利用しても、古いデータはメモリから消去されません! データを消去するには、imagedestroy() を使用する必要があります。( unset() も機能するかどうかはわかりません)。

また、メモリ内の画像データは未加工であるため、圧縮画像 (jpeg や png など) の元のファイル サイズに基づいて使用しているメモリ量を基にしないでください。

于 2013-02-08T09:35:58.690 に答える