开发者

reducing php memory usage for image resizing

I'm currently creating a PHP website where users need to be able to upload images, which then need to resized down to a reasonable size. My php configuration is set to a memory limit of 50mb.

The problem is when uploading images over around 5mb, php is not able to resize the image(due to to much memory use). So I was wondering if there's anyway to optimize memory usage of a resizing images. Here's what I currently use:

class Image {


  var $uploaddir;
  var $quality = 80;
  var $ext;
  var $dst_r;
  var $img_r;
  var $img_w;
  var $img_h;
  var $output;
  var $data;
  var $datathumb;

  function setFile($src = null) {
   $this->ext = strtoupper(pathinfo($src, PATHINFO_EXTENSION));
   if(is_file($src) && ($this->ext == "JPG" OR $this->ext == "JPEG")) {
    $this->img_r = ImageCreateFromJPEG($src);
   } elseif(is_file($src) && $this->ext == "PNG") {
    $this->img_r = ImageCreateFromPNG($src);      
   } elseif(is_file($src) && $this->ext == "GIF") {
    $this->img_r = ImageCreateFromGIF($src);
   }
   $this->img_w = imagesx($this->img_r);
   $this->img_h = imagesy($this->img_r);
  }

  function resize($largestSide = 100) {
    $width = imagesx($this->img_r);
    $height = imagesy($this->img_r);
    $newWidth = 0;
    $newHeight = 0;

  开发者_如何学运维  if($width > $height){
      $newWidth = $largestSide;
      $newHeight = $height * ($newWidth / $width);
    }else{
      $newHeight = $largestSide;
      $newWidth = $width * ($newHeight / $height);
    }

   $this->dst_r = ImageCreateTrueColor($newWidth, $newHeight);
   imagecopyresampled($this->dst_r, $this->img_r, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
   $this->img_r = $this->dst_r;
   $this->img_h = $newHeight;
   $this->img_w = $newWidth;
  }

  function createFile($output_filename = null) {
   if($this->ext == "JPG" OR $this->ext == "JPEG" OR $this->ext == "PNG" OR $this->ext == "GIF") {
    imageJPEG($this->dst_r, $this->uploaddir.$output_filename.'.'."jpg", $this->quality);
   } /*elseif($this->ext == "PNG") {
    imagePNG($this->dst_r, $this->uploaddir.$output_filename.'.'.$this->ext);
   } elseif($this->ext == "GIF") {
    imageGIF($this->dst_r, $this->uploaddir.$output_filename.'.'.$this->ext);
   }*/
   $this->output = $this->uploaddir.$output_filename.'.'.$this->ext;
  }

  function setUploadDir($dirname) {
   $this->uploaddir = $dirname;
  }

  function flush() {
   $tempFile = $_FILES['Filedata']['tmp_name'];
   $targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
   $targetFile = str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];

   imagedestroy($this->dst_r);
   unlink($targetFile);
   imagedestroy($this->img_r);

  }

And then for resizing I do:

  $tempFile = $_FILES['Filedata']['tmp_name'];
  $targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
  $targetFile =  str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];

  move_uploaded_file ($tempFile, $targetFile);

  $image = new Image();
  $image->setFile($targetFile);
  $image->setUploadDir($targetPath);
  $image->resize(200);
  $image->createFile(md5($id));
  $image->flush();

I'm current using uploadify, but it uses this upload / resize script. Is there anyway to optimize this code so that it uses less memory?

Thanks :)


a 5000 x 5000 pixel image would be 16.7 inches at 300DPI and that would come in at 5.2 Mb. you may want to set some reasonal expectation on image sizes, say about 10 megapixels?

a 14 megapixel image measures 4672 x 3104 and as a JPEG would fit well within a 5 Mb image size restriction.

also look and see if there is enough memory savings by using a palleted method such as imagecreate as opposed to imagecreatetruecolor.

there is also some help already on the php site for determining your memory requirements based on image size here


The pragmatic thing to do would be to just call an external program, e.g. ImageMagick to do the resizing.


Did you know that opening the file up with imagecreatefromjpeg uses a lot less memory than opening the first into a string (file_get_contents)- and then using imagecreatefromstring?

Also, I would limit file uploads to 2-4MB. There is no reason for people to waste your bandwidth sending huge files.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜