0

ユーザーが複数の画像をサーバー/ウェブサイトにアップロードできるウェブサイトを開発しています。アップロード スクリプトで、画像サイズの制限を 10MB に設定しました。これは、最近のカメラの多くが大きな画像を撮ると思っていたからです。

アップロード スクリプトは、各画像を 1 つずつ取得し、3 つの異なるバージョン、900x600、600x450、および小さいサムネイル画像にサイズ変更し、2 つの大きな画像の上に透かし画像を配置します。

php.ini の memory_limit を 96MB に設定しましたが、これで十分だと思いました。

少しテストした後、サイズが 6.38MB、解像度が 6143 x 3855 px の jpg 画像をアップロードしました。「致命的なエラー: 100663296 バイトの許容メモリ サイズが使い果たされました (24572 バイトを割り当てようとしました)」というエラー メッセージを受け取りました。

このサイズの画像をアップロードして処理するために、これほど多くのメモリが必要になるのは合理的だと思いますか? それとも、私のスクリプトのコーディングに問題がある可能性が高いと思いますか?

96 MB のメモリ制限は、私には多すぎるように思えます。大きな画像のアップロードを扱った他の人々の経験は何ですか? メモリ制限を 128MB 以上に設定する必要がありますか? または、アップロード スクリプトの書き直しを検討する必要がありますか。

私のコードは以下に追加されています:

      //If a new image has been added, resize and upload to filesystem
      if ($_FILES['new_image']['name'] !=''){

          $allowed_types=array(
            'image/gif' => '.gif',
            'image/jpeg' => '.jpg',
            'image/png' => '.png',
            'image/x-png' => '.png',
            'image/pjpeg' => '.jpg'
          );

          $img = $_FILES['new_image'];

          // Check the file to be uploaded is the correct file type and is under 9MB              

          if ((array_key_exists($img['type'], $allowed_types)) && ($img['size'] < 9000000))              {
          // File to be uploaded is Valid


          // File to be uploaded is Valid

          $imagename = stripslashes($_FILES['new_image']['name']);

          // make the random file name
          $randName = md5(rand() * time());
          $ext = pathinfo($imagename, PATHINFO_EXTENSION); 


          $imagename = $randName . "." . $ext;
          $source = $_FILES['new_image']['tmp_name'];


          // Check if Directory Exists, if not create it
          if(!file_exists("images/breeds/".$trimmed['profile_id']))
          { 
               mkdir("images/breeds/".$trimmed['profile_id']) or die("Could not create images folder for article ".$trimmed['profile_id']);
          } 

          // Check if thumbnail Directory Exists
          if(!file_exists("images/breeds/".$trimmed['profile_id']."/thumbs")) 
          { 
              mkdir("images/breeds/".$trimmed['profile_id']."/thumbs") or die("Could not create thumbnail folder for article ".$trimmed['profile_id']);
          } 

          // Check if thumbnail Directory Exists
          if(!file_exists("images/breeds/".$trimmed['profile_id']."/large")) 
          { 
              mkdir("images/breeds/".$trimmed['profile_id']."/large") or die("Could not create thumbnail folder for article ".$trimmed['profile_id']);
          } 


          $LargeImage = "images/breeds/".$trimmed['profile_id']."/large/".$imagename;
          $NormalImage = "images/breeds/".$trimmed['profile_id']."/".$imagename;
          $SmallImage = "images/breeds/".$trimmed['profile_id']."/thumbs/".$imagename;

          //uploaded temp file
          $file = $_FILES['new_image']['tmp_name'];


          //Get Image size info
          list($width, $height, $image_type) = getimagesize($file);

          //SourceImage
          switch ($image_type) 
          {
            case 1: $image = imagecreatefromgif($file); break;
            case 2: $image = imagecreatefromjpeg($file);  break;
            case 3: $image = imagecreatefrompng($file); break;
            default:  trigger_error('Unsupported filetype!', E_USER_WARNING);  break;
          }


          // Constraints for Large Image 
          $max_width = 900; 
          $max_height = 600; 
          $ratioh = $max_height/$height; 
          $ratiow = $max_width/$width; 
          $ratio = min($ratioh, $ratiow); 

          if (($height < $max_height) && ($width < $max_width)) {
           //keep same dimensions
           $modwidth = $width;
           $modheight = $height;
          } else {
          // New dimensions 
          $modwidth = intval($ratio*$width); 
          $modheight = intval($ratio*$height);
          }

          $tmpLarge = imagecreatetruecolor( $modwidth, $modheight );

          imagecopyresampled($tmpLarge, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ; 

          // Add Watermark to large image at top right

          $wm = "images/p4h-wm-200.png";
          $wmImage = imagecreatefrompng($wm); 
          $wmW = imagesx($wmImage); 
          $wmH = imagesy($wmImage); 

          $photoW = imagesx($tmpLarge); 
          $photoH = imagesy($tmpLarge);
          $dest_x = $photoW - $wmW - 10; 
          $dest_y = 10;

          // imagecopymerge($tn, $wmImage, $dest_x, $dest_y, 0, 0, $wmW, $wmH, 100); 
          imagecopy($tmpLarge, $wmImage, $dest_x, $dest_y, 0, 0, $wmW, $wmH);


          switch ($image_type) 
          {
             case 1: imagegif($tmpLarge,$LargeImage); break;
             case 2: imagejpeg($tmpLarge,$LargeImage, 80);  break;
             case 3: imagepng($tmpLarge,$LargeImage, 0); break;
             default:  trigger_error('Failed resize image!', E_USER_WARNING);  break;
          }


          // Destroy tmp images to free memory
          imagedestroy($tmpLarge);
          imagedestroy($wmImage);


          // Constraints for Normal Image 
          $max_width = 550; 
          $max_height = 413; 
          $ratioh = $max_height/$height; 
          $ratiow = $max_width/$width; 
          $ratio = min($ratioh, $ratiow); 

          if (($height < $max_height) && ($width < $max_width)) {
           //keep same dimensions
           $modwidth = $width;
           $modheight = $height;
          } else {
          // New dimensions 
          $modwidth = intval($ratio*$width); 
          $modheight = intval($ratio*$height);
          }

          $tmpNormal = imagecreatetruecolor( $modwidth, $modheight );

          imagecopyresampled($tmpNormal, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ; 

          // Add Watermark to large image at top right

          $wm = "images/p4h-wm-150.png";
          $wmImage = imagecreatefrompng($wm); 
          $wmW = imagesx($wmImage); 
          $wmH = imagesy($wmImage); 

          $photoW = imagesx($tmpNormal); 
          $photoH = imagesy($tmpNormal);
          $dest_x = $photoW - $wmW - 10; 
          $dest_y = 10;

          // imagecopymerge($tn, $wmImage, $dest_x, $dest_y, 0, 0, $wmW, $wmH, 100); 
          imagecopy($tmpNormal, $wmImage, $dest_x, $dest_y, 0, 0, $wmW, $wmH);

          switch ($image_type) 
          {
             case 1: imagegif($tmpNormal,$NormalImage); break;
             case 2: imagejpeg($tmpNormal,$NormalImage, 90);  break;
             case 3: imagepng($tmpNormal,$NormalImage, 0); break;
             default:  trigger_error('Failed resize image!', E_USER_WARNING);  break;
          }

          // Destroy tmp images to free memory
          imagedestroy($tmpNormal);
          imagedestroy($wmImage);


          // Now that the full size image has been saved, resize the thumbnail one to a fixed size for homepage display
          // Constraints 
          $thumb_width = 150; 
          $thumb_height = 112.5; 

         // Calculate stuff and resize image accordingly     
         $src_ratio = $width/$height;
         $dst_ratio = $thumb_width/$thumb_height;
         if($src_ratio < $dst_ratio) // trim top and bottom
         {
            $ratio = $width/$thumb_width;
            $crop_height = $thumb_height*$ratio;
            $src_y = round(($height-$crop_height)/2);
            $crop_width = $width;
            $src_x = 0;
         }
         else // trim left and right
         {
            $ratio = $height/$thumb_height;
            $crop_width = $thumb_width*$ratio;
            $src_x = round(($width-$crop_width)/2);
            $crop_height = $height;
            $src_y = 0;
         }


          $tmpSmall = imagecreatetruecolor( $thumb_width, $thumb_height );

          imagecopyresampled($tmpSmall, $image, 0, 0, $src_x, $src_y, $thumb_width, $thumb_height, $crop_width, $crop_height);

          switch ($image_type) 
          {
             case 1: imagegif($tmpSmall,$SmallImage); break;
             case 2: imagejpeg($tmpSmall,$SmallImage, 90);  break;
             case 3: imagepng($tmpSmall,$SmallImage, 0); break;
             default:  trigger_error('Failed resize image!', E_USER_WARNING);  break;
          }

        // Destroy images to free memory
        imagedestroy($image);
        imagedestroy($tmpSmall);
4

3 に答える 3

0

6143x3855イメージには、生のピクセルデータ用に少なくとも71,043,795バイトのメモリが必要です(ピクセルあたり3バイト)次に、オリジナルのサイズ変更されたバージョンなどを保持するために、他の一連の画像を作成します。

メモリが不足しているのも不思議ではありません。

于 2012-03-01T16:18:26.640 に答える
0

jpg は 6.38MB ですが、画像を変換するために使用される内部表現は生の非圧縮のものです。

あなたの画像は23.6メガピクセルです

非圧縮表現は、1 ピクセルあたり 32 ビット (4 バイト)、つまり 4*23.6M バイト = 94 M バイトになります。

ですから、処理するためにそんなに大きな画像が必要ですか?

はいの場合は、memory_limit を大きくしてください。いいえの場合は、アップロード可能な画像のサイズを、メモリ設定内で処理するのに適切なサイズに制限してください。

于 2012-03-01T16:01:07.340 に答える
0

おそらく、メモリをいつ解放できるかについて、PHP にさらにヒントを与える必要があります。通常はシンプル$some_variable = null;で十分です。

画像 (メイン画像とその各サムネイル) が完成したら、参照変数を に設定しnullてメモリを解放します。

それ以外の場合は、スクリプトの先頭とスクリプト全体のさまざまな場所でmemory_get_usage()( http://www.php.net/manual/en/function.memory-get-usage.php )の結果を印刷またはログに記録して追跡してみてください。メモリが行き詰まるところ。

于 2012-03-01T16:01:49.807 に答える