2012-03-01 26 views
0

私はアップロードスクリプトでサーバ/ウェブサイトに複数の画像をアップロードできるウェブサイトを開発しましたが、画像サイズの制限は10MBです。これは、現代の多くのカメラが大きな画像を撮ると思ったからです。PHP画像アップロードとサイズ変更でメモリ不足(96MBメモリ制限)

アップロードスクリプトは、各画像を一度に1つずつ取り込み、900x600,600x450の3種類のサムネイル画像にサイズ変更し、2つの大きな画像の上にウォーターマーク画像を配置します。

私はphp.ini memory_limitを96MBに設定しましたが、これは十分簡単だと思います。

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

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

96MBのメモリ制限が私には多分あるようです。大きな画像のアップロードを扱う他の人々の体験は何ですか?メモリ制限を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); 
+3

あなたはあなたがそれらを完了した後にイメージを破壊/解放していますか?一度に4枚の画像を開いたり、連続して作成、保存、破棄していますか? – horatio

+0

コードを転記すると役立ちます。また、どのライブラリ/ツールを使用してイメージのサイズを変更していますか? – masnun

+0

上記に追加されたコードを参照してください – user1052096

答えて

0

JPGは6.38メガバイトですが、画像を変換するために、使用する内部表現は、生の非圧縮の一つです。 4 * 23.6MBytes = 94メガバイト:

あなたのイメージは、ピクセルあたり23.6メガピクセル

それの非圧縮表現は可能性が32ビット(4バイト)、すなわちです。

だから、私は、あなたはそのような大きな画像を処理する必要があると言いますか?

もしそうなら、memory_limitを高く設定してください。 アップロードするイメージのサイズをメモリ設定内で処理するより妥当なものに制限してください。

+0

ウェブサイトは、人々が広告に画像をアップロードする広告ウェブサイトです。私は合理的なサイズの画像をアップロードできるようにしたいと思っています。毎回誰かが画像をアップロードしようとしたときに、それが大きすぎると言って戻ってくるのであれば、迷惑になるでしょう。 – user1052096

+0

だから、その場合は、私は少なくとも256 MBのPHPのメモリ制限を置くと、あなたが本当に大きすぎる場合にイメージを処理しようとする前に、アップロードスクリプトの迅速な計算を実行することをお勧めします。 – dweeves

0

メモリを解放できるときは、おそらくPHPにヒントを与える必要があります。通常は単純な$some_variable = null;で十分です。

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

それ以外の場合は、スクリプトの上部とスクリプト全体のさまざまな場所にあるmemory_get_usage()http://www.php.net/manual/en/function.memory-get-usage.php)の結果をプリントアウトするか、ログに記録してください。

+0

画像を書き終わったらメモリを解放するためにimagedestroy()を使用しています。上記の私のコードを見てください。 – user1052096

0

6143x3855の画像は、単に生のピクセルデータ(ピクセル当たり3バイト)のためのメモリのAT LEAST 71043795バイトを必要とするであろう。次に、オリジナルのサイズ変更されたバージョンを保持する一連の他の画像を作成します。

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

+0

私のスクリプトのように見えるかもしれません、おそらく256MBに私のメモリの制限を増やす必要があります。 – user1052096