0

このスクリプトで画像のサイズを変更して出力しました:

<?php
/**
 * Produce a preview of the picture
 *
 */
class CtrlImagePreview {

    const EXT_DOC = 'doc';
    const EXT_FILE = 'file';
    const EXT_XLS = 'xls';


    /**
     * Get the appropriate icon in function of the extension
     * @param string $ext
     */
    public function icon($ext) {

        //put the extension in lowercase
        $ext = strtolower($ext);

        //check if icon exist
        if(file_exists('picture/icon/'.$ext.'.png')) {

            //display the approriate icon
            $url = 'picture/icon/'.$ext.'.png';

        } else {

            //display 
            $url = 'picture/icon/file.png';
        }

        header("Cache-Control: private, max-age=10800, pre-check=10800");
        header("Pragma: private");
        header("Expires: " . date(DATE_RFC822,time()+60*60*24*30));
        header('Content-Type: image/png');
        header('Content-Transfer-Encoding: binary');
        readfile($url);
    }

    /**
     * Resize and output preview of the image
     * @param File $file
     */
    public function resize(File $file) {
        header("Cache-Control: private, max-age=10800, pre-check=10800");
        header("Pragma: private");
        header("Expires: " . date(DATE_RFC822,time()+60*60*24*30));

        header('Content-Type: image/png');
        header('Content-Transfer-Encoding: binary');

        $this->image('../upload/'.$_SESSION['c']->getId().'/'.$file->getProject()->getId().'/'.$file->getName(), true, 45);
    }


    /**
     * NOTE: this function has been imported for image resizing, output mime: image/jpeg
     * @param unknown_type $image
     * @param unknown_type $crop
     * @param unknown_type $size
     * @return boolean
     */
    private function image($image, $crop = null, $size = null) {
        $image = ImageCreateFromString(file_get_contents($image));

        if (is_resource($image) === true) {
            $x = 0;
            $y = 0;
            $width = imagesx($image);
            $height = imagesy($image);

            /*
             CROP (Aspect Ratio) Section
            */

            if (is_null($crop) === true) {
                $crop = array($width, $height);
            } else {
                $crop = array_filter(explode(':', $crop));

                if (empty($crop) === true) {
                    $crop = array($width, $height);
                } else {
                    if ((empty($crop[0]) === true) || (is_numeric($crop[0]) === false)) {
                        $crop[0] = $crop[1];
                    } else if ((empty($crop[1]) === true) || (is_numeric($crop[1]) === false)) {
                        $crop[1] = $crop[0];
                    }
                }

                $ratio = array(0 => $width / $height, 1 => $crop[0] / $crop[1]);

                if ($ratio[0] > $ratio[1]) {
                    $width = $height * $ratio[1];
                    $x = (imagesx($image) - $width) / 2;
                }

                else if ($ratio[0] < $ratio[1]) {
                    $height = $width / $ratio[1];
                    $y = (imagesy($image) - $height) / 2;
                }

            }

            /*
             Resize Section
            */

            if (is_null($size) === true) {
                $size = array($width, $height);
            }

            else {
                $size = array_filter(explode('x', $size));

                if (empty($size) === true) {
                    $size = array(imagesx($image), imagesy($image));
                } else {
                    if ((empty($size[0]) === true) || (is_numeric($size[0]) === false)) {
                        $size[0] = round($size[1] * $width / $height);
                    } else if ((empty($size[1]) === true) || (is_numeric($size[1]) === false)) {
                        $size[1] = round($size[0] * $height / $width);
                    }
                }
            }

            $result = ImageCreateTrueColor($size[0], $size[1]);

            if (is_resource($result) === true) {
                ImageSaveAlpha($result, true);
                ImageAlphaBlending($result, true);
                ImageFill($result, 0, 0, ImageColorAllocate($result, 255, 255, 255));
                ImageCopyResampled($result, $image, 0, 0, $x, $y, $size[0], $size[1], $width, $height);

                ImageInterlace($result, true);
                Imagepng($result, null, 0);
            }
        }

        return false;
    }
}

?>

問題は、このスクリプトが機能する場合と機能しない場合があり、大きな画像では機能していないように見えることです (私のサーバーでのみ、ローカル モードでは問題ありません!)。

このスクリプトによって生成された画像は次のとおりです。

画像プレビュー

4

2 に答える 2

2

明らかではないかもしれませんが、PHP関数を使用して画像を操作すると、画像はメモリ内で非圧縮になります。解像度が2500×1500(約4 MPixの画像)の1 MB JPEG写真がある場合、非圧縮サイズは2500×1500(解像度)×4(バイト/ピクセル)=15MBです。さらに圧縮されたJPEGを使用すると、圧縮データと非圧縮データの比率を簡単に1:30以上にすることができます。また、画像を正しく操作するには、この2倍の使用可能なメモリ(入力画像出力用)が必要になる場合もあります。

通常の解決策は、(PHPの構成で)メモリ制限を増やすかmemory_limit、ImageMagickなどの外部ライブラリを使用することです。

于 2012-04-16T17:46:57.783 に答える
1

大きな画像は、サイズ変更に多くのメモリを必要とします。多くの場合、使用されるメモリは、(たとえば) mod_php が最大として割り当てられた量を超えます。私は以前、ある種のキュー (データベース、または単に特定のディレクトリに配置することによって) を介して、画像ファイル名を外部プロセスに送信し、コマンドラインベースの PHP スクリプト (またはその他の画像サイズ変更プログラム) 必要なだけのメモリを使用してアクションを実行し、新しいコピーをどこかに配置します。

必要に応じて、そのようなキューをどのように配置するかについて、他にもいくつか質問があります。

于 2012-04-16T16:49:12.487 に答える