уменьшение использования памяти php для изменения размера изображения - PullRequest
1 голос
/ 06 января 2011

В настоящее время я создаю веб-сайт PHP, где пользователи должны иметь возможность загружать изображения, которые затем необходимо уменьшить до разумного размера. Моя конфигурация php установлена ​​на ограничение памяти 50 МБ.

Проблема в том, что при загрузке изображений размером более 5 Мб php не может изменить размер изображения (из-за большого использования памяти). Поэтому мне было интересно, есть ли возможность оптимизировать использование памяти для изменения размера изображений. Вот что я сейчас использую:

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);

  }

А затем для изменения размера я делаю:

  $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();

Я использую uploadify, но он использует этот скрипт загрузки / изменения размера. Есть ли способ оптимизировать этот код, чтобы он занимал меньше памяти?

Спасибо:)

Ответы [ 3 ]

2 голосов
/ 06 января 2011

изображение с разрешением 5000 x 5000 пикселей будет иметь разрешение 16,7 дюйма при разрешении 300 точек на дюйм и 5,2 МБ.Возможно, вы захотите установить некоторое разумное ожидание для размеров изображения, скажем, около 10 мегапикселей?

a 14-мегапиксельное изображение имеет размер 4672 x 3104, и, как JPEG, хорошо бы вписалось в ограничение размера изображения 5 Мб.

также посмотрите, достаточно ли экономии памяти при использовании метода на поддонах, такого как imagecreate, в отличие от imagecreatetruecolor.

на сайте php уже есть некоторая помощь для определения требований к памяти на основе размера изображения здесь

0 голосов
/ 06 января 2011

Знаете ли вы, что при открытии файла с помощью imagecreatefromjpeg используется намного меньше памяти, чем при открытии первого в строку (file_get_contents), а затем с использованием imagecreatefromstring?

Кроме того, я бы ограничил загрузку файлов до 2-4 МБ. У людей нет причин тратить вашу пропускную способность, отправляя огромные файлы.

0 голосов
/ 06 января 2011

Прагматично было бы просто вызвать внешнюю программу, например ImageMagick, для изменения размера.

...