Перейти к основному содержанию

Изменение размера изображения средствами PHP

Опубликовано 5.05.2011 Теги: php

Постоянно нам приходится принимать от пользователей различные данные. Довольно часто в этих данных встречаются изображения, которые необходимо сохранить на сервере для дальнейшего использования. Для того чтобы все загруженные изображения одинаково вписывались в общий дизайн сайта, либо занимали меньше дискового пространства, нам необходимо изменять размеры изображения. Конечно, есть функции для проверки ширины и высоты, но согласитесь, будет некорректно сообщать пользователю, что изображение не подходит для вашего сайта.

На этот случай у меня есть один хороший класс под название SimpleImage, который позволяет довольно гибко изменять размеры изображения.

<?php
class SimpleImage {

   var $image;
   var $image_type;

   function load($filename) {
      $image_info = getimagesize($filename);
      $this->image_type = $image_info[2];
      if( $this->image_type == IMAGETYPE_JPEG ) {
         $this->image = imagecreatefromjpeg($filename);
      } elseif( $this->image_type == IMAGETYPE_GIF ) {
         $this->image = imagecreatefromgif($filename);
      } elseif( $this->image_type == IMAGETYPE_PNG ) {
         $this->image = imagecreatefrompng($filename);
      }
   }
   function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image,$filename,$compression);
      } elseif( $image_type == IMAGETYPE_GIF ) {
         imagegif($this->image,$filename);
      } elseif( $image_type == IMAGETYPE_PNG ) {
         imagepng($this->image,$filename);
      }
      if( $permissions != null) {
         chmod($filename,$permissions);
      }
   }
   function output($image_type=IMAGETYPE_JPEG) {
      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image);
      } elseif( $image_type == IMAGETYPE_GIF ) {
         imagegif($this->image);
      } elseif( $image_type == IMAGETYPE_PNG ) {
         imagepng($this->image);
      }
   }
   function getWidth() {
      return imagesx($this->image);
   }
   function getHeight() {
      return imagesy($this->image);
   }
   function resizeToHeight($height) {
      $ratio = $height / $this->getHeight();
      $width = $this->getWidth() * $ratio;
      $this->resize($width,$height);
   }
   function resizeToWidth($width) {
      $ratio = $width / $this->getWidth();
      $height = $this->getheight() * $ratio;
      $this->resize($width,$height);
   }
   function scale($scale) {
      $width = $this->getWidth() * $scale/100;
      $height = $this->getheight() * $scale/100;
      $this->resize($width,$height);
   }
   function resize($width,$height) {
      $new_image = imagecreatetruecolor($width, $height);
      imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
      $this->image = $new_image;
   }
}
?>

Скачать клаcc SimpleImage

Теперь после того как мы поместили данный файл класса SimpleImage к себе на сервер посмотрим как его можно использовать.

Следующий участок кода загрузит изображение image.jpg, изменить его ширину до 400 пикселей и высоту до 200 пикселей, а затем сохранит как image1.jpg.

<?php
   include('classSimpleImage.php');
   $image = new SimpleImage();
   $image->load('image.jpg');
   $image->resize(400, 200);
   $image->save('image1.jpg');
?>

Если необходимо изменить размеры изображения, основываясь только на ширине и при этом сохранить его пропорции, то сценарий сам выберет необходимую высоту. Для этого необходимо использовать метод resizeToWidth.

<?php
   include('classSimpleImage.php');
   $image = new SimpleImage();
   $image->load('image.jpg');
   $image->resizeToWidth(250);
   $image->save('image1.jpg');
?>

Возможно вы пожелаете изменить размер в процентном соотношении от его оригинала. Для этого существует метод scale, в качестве параметра которому передаются проценты.

<?php
   include('classSimpleImage.php');
   $image = new SimpleImage();
   $image->load('image.jpg');
   $image->scale(50);
   $image->save('image1.jpg');
?>

У данного класса есть еще один очень полезный метод output, который позволяет выводить изображения прямо в браузер, без предварительного сохранения. Данный метод может быть очень полезен при создании миниатюр.

<?php
   header('Content-Type: image/jpeg');
   include('classSimpleImage.php');
   $image = new SimpleImage();
   $image->load('image.jpg');
   $image->resizeToWidth(150);
   $image->output();
?>

Автор данного класса Simon Jarvis, на своем сайте предлагает следующий пример для изменения размера изображения загруженного через форму.

<?php
if (isset($_POST['submit']) ) {
    include('classSimpleImage.php');
    $image = new SimpleImage();
    $image->load($_FILES['uploaded_image']['tmp_name']);
    $image->resizeToWidth(150);
    $image->output();
}
else {
  $form = '<form action="upload.php" method="post" enctype="multipart/form-data">
      <input type="file" name="uploaded_image" />
      <input type="submit" name="submit" value="Upload" />
    </form>';
  echo $form;
}

Вот такой очень маленький, но довольно функциональный получился класс SimpleImage, который очень пригодиться любому разработчику.

Github

Комментарии

Аватар пользователя Freeron
Freeron
Опубликовано 4.08.2013

Согласен, класс действительно функциональный, а использование интуитивно понятно.Самому как-то приходилось писать скрипт для загрузки и ресайза изображений, но не писал для него класс...PS. Можем обменяться постовыми, если желаете)

  • ответить
Аватар пользователя Pavel  Holovko
Pavel Holovko
Опубликовано 4.08.2013

Спасибо. Помогла твоя статья.

  • ответить
Аватар пользователя Zhzz
Zhzz
Опубликовано 4.08.2013

Благодарю, хорошее решение.

  • ответить
Аватар пользователя One
One
Опубликовано 4.08.2013

Как-будто спижжено с WideImage Library

  • ответить
Аватар пользователя Андрей
Андрей
Опубликовано 4.08.2013

Утянул, спасибо

  • ответить
Аватар пользователя Info
Info
Опубликовано 4.08.2013

Спасибо!

  • ответить
Аватар пользователя Shaloshvili
Shaloshvili
Опубликовано 4.08.2013

буду ломать голову, спасибо, есть теперь над чем)

  • ответить
Аватар пользователя Edishions
Edishions
Опубликовано 4.08.2013

Спасибо. Только ваша статья помогла.

  • ответить
Аватар пользователя Loskand
Loskand
Опубликовано 4.08.2013

код может и фурычит, вот только include не фурычит, ругается что не может найти файл с классом хотя и адрес верный ввожу и сам файл работоспособный.

  • ответить
Аватар пользователя Ярчик
Ярчик
Опубликовано 4.08.2013

при подлючении в коде указан "SimpleImage.php", а в архиве файл с названием "classSimpleImage.php". Переименуйте файл или же допишите слово class в пути подключения скрипта =)

  • ответить
Аватар пользователя Alexander Schedrov
Alexander Schedrov
Опубликовано 4.08.2013

Спасибо! Исправил

  • ответить
Аватар пользователя Ivinnic
Ivinnic
Опубликовано 4.08.2013

Спасибо, очень помогла статья, особенно то как сохранить изображение)Действительно очень функциональный класс!

  • ответить
Аватар пользователя Ярчик
Ярчик
Опубликовано 4.08.2013

Никак не могу разобраться с выводом output! Нужны именно миниатюры фотографий, без сохранения.

&#10;load(&#039;2.jpg&#039;);&#10;//Изображение лежит именно в той папке, где и скрипт (на всякий, пожарный)&#10;$image-&gt;resizeToWidth(100);&#10;//нужна ширина в 100 пикселей&#10;$image-&gt;output();&#10;//это кудЫ?)&#10;
<img alt="" class="gallery" src="codes/2.jpg"> 

Объясните, пожалуйста, как же вывести нашу миниатюру!

  • ответить
Аватар пользователя Gwartur
Gwartur
Опубликовано 4.08.2013

Отличная работа. Коллега. Классная инкапсуляция стандартный функций.

  • ответить
Аватар пользователя Denis
Denis
Опубликовано 4.08.2013

а это куда всовывать? "Retaining Transparency with PHP Image Resizing" http://www.white-hat-web-desig...

  • ответить
Аватар пользователя Igor Ovseychuk
Igor Ovseychuk
Опубликовано 4.08.2013

Спасибо большое! Отличный класс

  • ответить
Аватар пользователя alex
alex
Опубликовано 4.08.2013

Спасибо, хороший класс. Добавил в него свой метод, который вырезает из картинки эллипс - столкнулся с проблемой сохранения прозрачности. Сделал по умолчанию выходной формат PNG, добавил в метод load() строчки: imagealphablending($this->image,false); imagesavealpha($this->image,true); а в метод ellipse(): imagealphablending($im,true); - проблема решена. Следует учесть, что эти строки должны быть прописаны сразу после создания изображения.

  • ответить
Аватар пользователя Alexander Schedrov
Alexander Schedrov
Опубликовано 4.08.2013

Спасибо большое за отзыв! Очень полезная информация.

  • ответить
Аватар пользователя alex
alex
Опубликовано 4.08.2013

Я просто подумал что если делать ресайз изображения, в котором присутствуют прозрачные элементы, может возникнуть проблема, хотя не пробовал честно говоря)

  • ответить
Аватар пользователя Евгений
Евгений
Опубликовано 14.06.2016

Сделал по умолчанию выходной формат PNG, добавил в метод load() строчки: imagealphablending($this->image,false); imagesavealpha($this->image,true); а в метод ellipse(): imagealphablending($im,true); - проблема решена.

Ребята, подскажите, куда вставлять эти строчки? Скрипт очень крутой, нужно сделать, чтоб фон прозрачный у png оставался...

  • ответить
Аватар пользователя Евгений
Евгений
Опубликовано 14.06.2016

Нашел немного редактированный класс, с ним все работает. Мало ли кому пригодится.:

<?php 
class SimpleImage {
   var $image;
   var $image_type;
   function load($filename) {
      $image_info = getimagesize($filename);
      $this->image_type = $image_info[2];
      if( $this->image_type == IMAGETYPE_JPEG ) {
         $this->image = imagecreatefromjpeg($filename);
      } elseif( $this->image_type == IMAGETYPE_GIF ) {
         $this->image = imagecreatefromgif($filename);
      } elseif( $this->image_type == IMAGETYPE_PNG ) {
         $this->image = imagecreatefrompng($filename);
      }
   }
   function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
        // do this or they'll all go to jpeg
        $image_type=$this->image_type;
        if( $image_type == IMAGETYPE_JPEG ) {
            imagejpeg($this->image,$filename,$compression);
        } elseif( $image_type == IMAGETYPE_GIF ) {
            imagegif($this->image,$filename);
        } elseif( $image_type == IMAGETYPE_PNG ) {
            // need this for transparent png to work
            imagealphablending($this->image, false);
            imagesavealpha($this->image,true);
            imagepng($this->image,$filename);
        }
        if( $permissions != null) {
            chmod($filename,$permissions);}
   }
   function output($image_type=IMAGETYPE_JPEG) {
      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image);
      } elseif( $image_type == IMAGETYPE_GIF ) {
         imagegif($this->image);
      } elseif( $image_type == IMAGETYPE_PNG ) {
         imagepng($this->image);
      }
   }
   function getWidth() {
      return imagesx($this->image);
   }
   function getHeight() {
      return imagesy($this->image);
   }
   function resizeToHeight($height) {
      $ratio = $height / $this->getHeight();
      $width = $this->getWidth() * $ratio;
      $this->resize($width,$height);
   }
   function resizeToWidth($width) {
      $ratio = $width / $this->getWidth();
      $height = $this->getheight() * $ratio;
      $this->resize($width,$height);
   }
   function scale($scale) {
      $width = $this->getWidth() * $scale/100;
      $height = $this->getheight() * $scale/100;
      $this->resize($width,$height);
   }
   function resize($width,$height,$forcesize='n') {
        /* optional. if file is smaller, do not resize. */
        if ($forcesize == 'n') {
            if ($width > $this->getWidth() && $height > $this->getHeight()){
                $width = $this->getWidth();
                $height = $this->getHeight();
            }
        }
        $new_image = imagecreatetruecolor($width, $height);
        /* Check if this image is PNG or GIF, then set if Transparent*/
        if(($this->image_type == IMAGETYPE_GIF) || ($this->image_type==IMAGETYPE_PNG)){
            imagealphablending($new_image, false);
            imagesavealpha($new_image,true);
            $transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
            imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent);
        }
        imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
        $this->image = $new_image;
    }
}

  • ответить
Аватар пользователя Ff
Ff
Опубликовано 4.08.2013

Если изначально картинка уже маленькая(а мы не знаем), и мы ее ресайзим до большего размера, то сохраняется большая картинка в плохом качестве. А должно наверно просто оставлять как есть.

  • ответить
Аватар пользователя Добров Константин
Добров Константин
Опубликовано 4.08.2013

Большое спасибо! Очень помогло! Спасло много времени! )))

  • ответить
Аватар пользователя Иван
Иван
Опубликовано 4.08.2013

А если изображение вертикальное, а нужно сделать его горизонтальным, то есть вырезать из него кусок заданного размера?

  • ответить
Аватар пользователя Кирилл
Кирилл
Опубликовано 4.08.2013

Спасибо большое автору!!

  • ответить
Аватар пользователя ♔Серёга♔
♔Серёга♔
Опубликовано 4.08.2013

Спасибо, то что искал))

  • ответить
Аватар пользователя Станислав
Станислав
Опубликовано 4.08.2013

Огромное спасибо!

  • ответить
Аватар пользователя Alexander Lapin
Alexander Lapin
Опубликовано 4.08.2013

Спасибо автору класса и автору статьи, очень помгло, хотел сам уже писать!

  • ответить
Аватар пользователя Vlode
Vlode
Опубликовано 4.08.2013

изображение ...путь изображения ... не может быть показано так как содержит ошибки, как исправить

  • ответить
Аватар пользователя Михаил
Михаил
Опубликовано 4.08.2013

Шикарно! Спасибо огромное! 2дня потратил на написание своего кода, но либо не загружал на сервер, либо загружал но не менял размер. Теперь всё работает :-)

  • ответить
Аватар пользователя Дмитрий
Дмитрий
Опубликовано 4.08.2013

большое спасибо, освоил работу с изображениями с помощью этого класса

  • ответить
Аватар пользователя Богдан
Богдан
Опубликовано 4.08.2013

Функция изминение двух сторон рисунка

function resizeToSize($width,$height) {
  $w_src = $this->getWidth();
  $h_src = $this->getHeight();
  $new_image = imagecreatetruecolor($width, $height);
  if ($w_src&gt;$h_src)
    imagecopyresampled($new_image, $this->image, 0, 0, round((max($w_src,$h_src)-min($w_src,$h_src))/2), 0, $width, $height, min($w_src,$h_src), min($w_src,$h_src)); //Вирізаємо квадратну середину по х, якщо малюнок горизонтальний
  if ($w_src&lt;$h_src)
    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, min($w_src,$h_src), min($w_src,$h_src)); //Вирізаємо квадратну середину по у, якщо малюнок вертикальний
  if ($w_src==$h_src)
    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $w_src, $w_src); //Змінюємо маштаб картинки        $this-&gt;image = $new_image;
}

  • ответить
Аватар пользователя Bykuznec
Bykuznec
Опубликовано 20.09.2013

Спасибо за класс, довольно понятно и просто все.

  • ответить
Аватар пользователя Олег
Олег
Опубликовано 3.10.2013

просьба подсказать что должно быть в файле upload.php на который ссылается форма, без него не работает.

  • ответить
Аватар пользователя Alexander Schedrov
Alexander Schedrov
Опубликовано 3.10.2013

Это и есть содержимое файла upload.php. Форма и обработчик в одном файле, это всеголишь в рамках примера.

  • ответить
Аватар пользователя Олег
Олег
Опубликовано 3.10.2013

все примеры работоспособны за исключением примера с формой, выдает след. сообщение:

Warning: getimagesize() [function.getimagesize]: Filename cannot be empty in Z:\home\start\www\classSimpleImage.php on line 28

Спс за оперативный ответ.

  • ответить
Аватар пользователя Максим
Максим
Опубликовано 25.11.2013

Есть необходимость уменьшать изображение при этом, чтобы качество было самым высоким.
Всегда использовал стандартное решение:
$size=GetImageSize ($uploadfile);
$src=ImageCreateFromJPEG ($uploadfile);
$iw=$size[0];
$ih=$size[1];
$koe=$iw/250;
$new_h=ceil ($ih/$koe);
$dst=ImageCreateTrueColor (250, $new_h);
ImageCopyResampled ($dst, $src, 0, 0, 0, 0, 250, $new_h, $iw, $ih);
ImageJPEG ($dst, $uploadfileS, 100);

Но как оказалось, что если уменьшить фото через фотошоп (cs6), то при одинаковых условиях в фотошопе уменьшенное фото имеет выше качество. Это заметно невооруженным глазом. Даже при том, что в функции ImageJPEG в третьем параметре стоит 100 %

Класс, который описан в статье как-то решает эту проблему или есть какие-то другие решения?

  • ответить
Аватар пользователя Alexander Schedrov
Alexander Schedrov
Опубликовано 5.12.2013

К сожалению не делал таких тестов, но вы всегда можете их сделать и поделиться результатом:)

  • ответить
Аватар пользователя Антон
Антон
Опубликовано 6.02.2014

Спасибо, хорошее описание на русском.

  • ответить
Аватар пользователя Евгений
Евгений
Опубликовано 16.04.2014

Все аккуратно, чисто и функционально.Спасибо!

  • ответить
Аватар пользователя Андрей
Андрей
Опубликовано 24.04.2014

Огромное СПАСИБО автору! Полезно!
ИМХО. Всё остальное - кому чего не хватает - уверен, каждый допишет лично.
Утянул.

  • ответить
Аватар пользователя Павел
Павел
Опубликовано 24.05.2014

Warning: imagejpeg(): Unable to open 'image1.jpg' for writing: Permission denied in /home/cloudtown/www/test/index.php on line 24
Выдает такую ошибку при использование

$image = new SimpleImage();
$image->load('image.jpg');
$image->resize(400, 200);
$image->save('image1.jpg');

  • ответить
Аватар пользователя Alexander Schedrov
Alexander Schedrov
Опубликовано 25.05.2014

Скорее всего у вас проблемы с правами на файл. Выполните в консоле:

sudo chmod 777 /home/cloudtown/www/test/image.jpg
  • ответить
Аватар пользователя Андрей
Андрей
Опубликовано 13.06.2014

Добрый день знатоки!

Ситуация такова, мне нужно сперва до определенной ширины пропорционально уменьшить входящее изображение, а потом отрезать от него фрагмент с левого верхнего угла. По отдельности imagecopyresampled - выполняет первую задачу, а imagecopy - вторую, но если обе функции в деле, то выполняется только вторая, как это можно решить?

function resize(){
    $ratio = $width / $this->getWidth();
    $height = $this->getheight() * $ratio;
    $width = 148;
    $height = 110;
    $w = $this->getWidth();
    $h = $this->getHeight();
    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
    imagecopy( $new_image, $this->image, 0, 0,  $width, $height, $w, $h);
    $this->image = $new_image;
    return $this->image;
}
function getWidth() {
     return imagesx($this->image);
}
function getHeight() {
     return imagesy($this->image);
}

  • ответить
Аватар пользователя Alexander Schedrov
Alexander Schedrov
Опубликовано 13.06.2014

Эта проблема связана с тем что вы всегда применяете операцию к исходному изображению. Что бы решить это, после первой операции imagecopyresampled() вам нужно обновить изображение объекта $this.

Пример:

function resize(){
    $ratio = $width / $this->getWidth();
    $height = $this->getheight() * $ratio;
    $width = 148;
    $height = 110;
    $w = $this->getWidth();
    $h = $this->getHeight();
    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
    // Устанавливаем новое уменьшенное изображение.
    $this->image = $new_image;
    // Здесь уже проводим операцию над уменьшенным изображением.
    imagecopy( $new_image, $this->image, 0, 0,  $width, $height, $w, $h);
    $this->image = $new_image;
    return $this->image;
}
function getWidth() {
     return imagesx($this->image);
}
function getHeight() {
     return imagesy($this->image);
}
  • ответить
Аватар пользователя Дмитриев Андрей
Дмитриев Андрей
Опубликовано 13.06.2014

Спасибо за отклик, но теперь у меня появляется только черный квадрат

  • ответить
Аватар пользователя Ольга
Ольга
Опубликовано 18.06.2014

Спасибо автору за статью!

Есть папка download в ней папка tmp.

При загрузке изображения загружаются в download,как сделать,чтобы они загружались в папку 'tmp'?

Если move_uploaded_file($temp,"tmp/".$name),то выдает ошибку и все равно сохраняет файлы в папку download.
Подскажите как решить вопрос!

  • ответить
Аватар пользователя Rustam
Rustam
Опубликовано 7.07.2014

Кому интересно, так же есть готовая функция, которую можно использовать для ресайзинга изображений.

  • ответить
Аватар пользователя Крекер
Крекер
Опубликовано 3.08.2014

Большое спасибо!!!!!

  • ответить
Аватар пользователя Кирилл
Кирилл
Опубликовано 28.08.2014

Спасибо! А вотермарки можно ставить?

  • ответить
Аватар пользователя Alexander Schedrov
Alexander Schedrov
Опубликовано 28.08.2014

К сожалению нельзя.

  • ответить
Аватар пользователя Serega
Serega
Опубликовано 28.11.2014

Вы можете добавлять водяные знаки точнее накладывать изображение как следует из документации по php

https://php.net/manual/en/image.examples-watermark.php

function watermark($stamps,$marge_right = 10,$marge_bottom = 10) {
    // Load the stamp and the photo to apply the watermark to
    $stamp = imagecreatefrompng($stamps);
// Set the margins for the stamp and get the height/width of the stamp image
    $sx = imagesx($stamp);
    $sy = imagesy($stamp);
// Copy the stamp image onto our photo using the margin offsets and the photo
// width to calculate positioning of the stamp.
    imagecopy($this->image, $stamp, imagesx($this->image) - $sx - $marge_right, imagesy($this->image) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp));
  }

  • ответить
Аватар пользователя Са П.
Са П.
Опубликовано 2.09.2014

Еще полезно будет прикрутить EXIF - http://plutov.by/post/ffmpeg_exif_rotate

  • ответить
Аватар пользователя Сергей
Сергей
Опубликовано 13.09.2014

Подскажите пожалуйста где в этом коде изменяется размер картинки и как задать свой размер? тут размер выходит 146х168, я уже 2 часа сижу не могу понять как это работает, мне нужно ширину 200px высоту авто или 250px. Жду вашей помощи)

<?php
/**
 * Augmentation to the $_SERVER['DOCUMENT_ROOT'] functionality, because it cannot be relied on to provide the right path
 * in cases where there is URL rewriting at play.
 *
 * @param  $path
 * @return mixed|string
 */
function inkthemes_document_root($path) {
    // If the file exists under DOCUMENT_ROOT, return DOCUMENT_ROOT
    if (@file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $path)) {
        return $_SERVER['DOCUMENT_ROOT'];
    }
    // Get the path of the current script, then compare it with DOCUMENT_ROOT. Then check for the file in each folder.
    $parts = array_diff(explode('/', $_SERVER['SCRIPT_FILENAME']), explode('/', $_SERVER['DOCUMENT_ROOT']));
    $new_path = $_SERVER['DOCUMENT_ROOT'];
    foreach ($parts as $part) {
        $new_path .= '/' . $part;
        if (@file_exists($new_path . '/' . $path)) {
            return $new_path;
        }
    }
    // Microsoft Servers
    if (!isset($_SERVER['DOCUMENT_ROOT'])) {
        $new_path = str_replace("/", "", $_SERVER['ORIG_PATH_INFO']);
        $new_path = str_replace($new_path, "", $_SERVER['SCRIPT_FILENAME']);
        if (@file_exists($new_path . '/' . $path)) {
            return $new_path;
        }
    }
    return false;
}
/**
 * This function resizes images It takes image source,
 * width height and quality as a parameter
 * This function is based on the approach described by
 * Victor Teixeira here: http://core.trac.wordpress.org/ticket/15311. * @param  $img_url
 * @param  $width
 * @param  $height
 * @param bool $crop
 * @param  $quality
 * @return array with image URL, width and height
 */
if ((function_exists('is_multisite') && is_multisite()) || ($single_site = true)) {
    function inkthemes_image_resize($img_url, $width, $height, $crop = true, $quality = 100) {
        $upload_dir = wp_upload_dir();
        // This used to be the directory for the image cache prior to 3.7.2, so we will leave it that way...
        //echo "</br uploadbase=>".
        $newfile = $upload_dir['basedir']; // base directory
        $newsubdir = '/thumb-cache'; //subdirectory like:2012/11
        $upload_path = $newfile . $newsubdir;
        //echo $upload_path = $upload_dir['path'];
        if (!file_exists($upload_path)) { // Create the directory if it is missing
            wp_mkdir_p($upload_path);
        }
        $file_path = parse_url($img_url);
        if (isset($file_path['host']) && $_SERVER['HTTP_HOST'] != $file_path['host'] && $file_path['host'] != '') {  // The image is not locally hosted
            $remote_file_info = pathinfo($file_path['path']); // Can't use $img_url as the parameter because pathinfo includes the 'query' for the URL
            if (isset($remote_file_info['extension'])) {
                $remote_file_extension = $remote_file_info['extension'];
            } else {
                $remote_file_extension = 'jpg';
            }
            $remote_file_extension = strtolower($remote_file_extension); // Not doing this creates multiple copies of a remote image.
            $file_base = md5($img_url) . '.' . $remote_file_extension;
            // We will try to copy the file over locally. Otherwise WP's native image_resize() breaks down.
            $copy_to_file = $upload_dir['path'] . '/' . $file_base;
            if (!file_exists($copy_to_file)) {
                $unique_filename = wp_unique_filename($upload_dir['path'], $file_base);
                // Using the HTTP API instead of our own CURL calls...
                $remote_content = wp_remote_request($img_url, array('sslverify' => false)); // Setting the sslverify argument, to prevent errors on HTTPS calls. A user embedding images in a post knows where he is pulling them from
                if (is_wp_error($remote_content)) {
                    $copy_to_file = '';
                } else {
                    // Not using file open functions, so you have to find your way around by using wp_upload_bits...
                    wp_upload_bits($unique_filename, null, $remote_content['body']);
                    $copy_to_file = $upload_dir['path'] . '/' . $unique_filename;
                }
            }
            $file_path = $copy_to_file;
        } else {
            $expath = $file_path['path'];
            $string = $expath;
            $find = '/files/';
            $findit = strpos($string, $find);
            //echo "</br> Findit=>".$findit;
            if ($findit === false) {
                $file_path = inkthemes_document_root($file_path['path']) . $file_path['path'];
            } else {
                $expath = $file_path['path'];
                $nefilepath = explode("/files", $expath);
                $newpathdir = $nefilepath[1];
                $filepath1 = $newfile . $newpathdir;
                $file_path = $filepath1;   // add to mainpath in $file_path
            }
        }
        if (!file_exists($file_path)) {
            $resized_image = array(
                'url' => $img_url,
                'width' => $width,
                'height' => $height
            );
            return $resized_image;
        }
        $orig_size = @getimagesize($file_path);
        $source[0] = $img_url;
        $source[1] = $orig_size[0];
        $source[2] = $orig_size[1];
        $file_info = pathinfo($file_path);
        $extension = '';
        if (isset($file_info['extension'])) {
            $extension = '.' . $file_info['extension'];
            //Image quality is scaled down in case of PNGs, because PNG image creation uses a different scale for quality.
            if ($extension == '.png' && $quality != null) {
                $quality = floor(0.09 * $quality);
            }
        }
        $crop_str = $crop ? '-crop' : '-nocrop';
        $quality_str = $quality != null ? '-' . $quality : '';
        $cropped_img_path = $upload_path . '/' . $file_info['filename'] . '-' . md5($file_path) . '-' . $width . 'x' . $height . $quality_str . $crop_str . $extension;
        $suffix = md5($file_path) . '-' . $width . 'x' . $height . $quality_str . $crop_str;
        //$img_path=str_replace($upload_dir['basedir'], $upload_dir['baseurl'], $cropped_img_path);
        // Checking if the file size is larger than the target size
        // If it is smaller or the same size, stop right here and return
        if ($source[1] > $width || $source[2] > $height) {
            // Source file is larger, check if the resized version already exists (for $crop = true but will also work for $crop = false if the sizes match)
            if (file_exists($cropped_img_path)) {
                $cropped_img_url = str_replace($upload_dir['basedir'], $upload_dir['baseurl'], $cropped_img_path);
                $resized_image = array(
                    'url' => $cropped_img_url,
                    'width' => $width,
                    'height' => $height
                );
                return $resized_image;
            }
            if ($crop == false) {
                // Calculate the size proportionally
                $proportional_size = wp_constrain_dimensions($source[1], $source[2], $width, $height);
                $resized_img_path = $upload_path . '/' . $file_info['filename'] . '-' . md5($file_path) . '-' . $proportional_size[0] . 'x' . $proportional_size[1] . $quality_str . $crop_str . $extension;
                $suffix = md5($file_path) . '-' . $proportional_size[0] . 'x' . $proportional_size[1] . $quality_str . $crop_str;
                // Checking if the file already exists
                if (file_exists($resized_img_path)) {
                    $resized_img_url = str_replace($upload_dir['basedir'], $upload_dir['baseurl'], $resized_img_path);
                    $resized_image = array(
                        'url' => $resized_img_url,
                        'width' => $proportional_size[0],
                        'height' => $proportional_size[1]
                    );
                    return $resized_image;
                }
            }
            $img = wp_get_image_editor($file_path);
            if (is_wp_error($img)) {
                $resized_image = array(
                    'url' => $source[0],
                    'width' => $source[1],
                    'height' => $source[2]
                );
            } else {
                $old_size = $img->get_size();
                $resize = $img->resize($width, $height, $crop);
                if ($resize !== FALSE) {
                    $new_size = $img->get_size();
                }
                $cropped_img_url = str_replace($upload_dir['basedir'], $upload_dir['baseurl'], $cropped_img_path);
                $img->save($cropped_img_path);
                // resized output
                $resized_image = array(
                    'url' => $cropped_img_url,
                    'width' => $new_size['width'],
                    'height' => $new_size['height']
                );
            }
            return $resized_image;
        }
        // default output - without resizing
        $resized_image = array(
            'url' => $source[0],
            'width' => $source[1],
            'height' => $source[2]
        );
        return $resized_image;
    }
} //multisite ends
/**
 * This function gets attachment id and resizes it
 * @param type $attach_id
 * @param type $img_url
 * @param type $width
 * @param type $height
 * @param type $crop
 * @param type $jpeg_quality
 * @return type
 */
function inkthemes_thumbnail_resize($attach_id = null, $img_url = null, $width, $height, $crop = false, $jpeg_quality = 90) {
    // this is an attachment, so we have the ID
    if ($attach_id) {
        $image_src = wp_get_attachment_image_src($attach_id, 'full');
        $file_path = get_attached_file($attach_id);
        // this is not an attachment, let's use the image url
    } else if ($img_url) {
        $file_path = parse_url($img_url);
        $file_path = ltrim($file_path['path'], '/');
        $file_path = rtrim(ABSPATH, '/') . $file_path['path'];
        $orig_size = getimagesize($file_path);
        $image_src[0] = $img_url;
        $image_src[1] = $orig_size[0];
        $image_src[2] = $orig_size[1];
    }
    $file_info = pathinfo($file_path);
    $extension = '.' . $file_info['extension'];
    // the image path without the extension
    $no_ext_path = $file_info['dirname'] . '/' . $file_info['filename'];
    $cropped_img_path = $no_ext_path . '-' . $width . 'x' . $height . $extension;
    // checking if the file size is larger than the target size
    // if it is smaller or the same size, stop right here and return
    if ($image_src[1] > $width || $image_src[2] > $height) {
        // the file is larger, check if the resized version already exists (for crop = true but will also work for crop = false if the sizes match)
        if (file_exists($cropped_img_path)) {
            $cropped_img_url = str_replace(basename($image_src[0]), basename($cropped_img_path), $image_src[0]);
            $vt_image = array(
                'url' => $cropped_img_url,
                'width' => $width,
                'height' => $height
            );
            return $vt_image;
        }
        // crop = false
        if ($crop == false) {
            // calculate the size proportionaly
            $proportional_size = wp_constrain_dimensions($image_src[1], $image_src[2], $width, $height);
            $resized_img_path = $no_ext_path . '-' . $proportional_size[0] . 'x' . $proportional_size[1] . $extension;
            // checking if the file already exists
            if (file_exists($resized_img_path)) {
                $resized_img_url = str_replace(basename($image_src[0]), basename($resized_img_path), $image_src[0]);
                $vt_image = array(
                    'url' => $resized_img_url,
                    'width' => $proportional_size[0],
                    'height' => $proportional_size[1]
                );
                return $vt_image;
            }
        }
        // new function replacing image_resize()
        $img = wp_get_image_editor($file_path);
        if (!is_wp_error($img)) {
            $old_size = $img->get_size();
            // To show image old width and height as echo $old_size['width']
            $resize = $img->resize($width, $height, $crop);
            //$img->set_quality(90);
            // $resize1=$img->crop( 100, 80, $width-100, $height-80, $width, $height, false );
            if ($resize !== FALSE) {
                $new_size = $img->get_size();
                // To show image new width and height as echo $new_size['width']
            }
            //$name_file=rand().basename($file_path);
            $path = str_replace(basename($image_src[0]), '', $image_src[0]);
            $filename = $img->generate_filename('final' . $width, $path . '/', NULL);
            $image_detail = $img->save($filename);
        }
        $new_img = str_replace(basename($image_src[0]), basename($image_detail['path']), $image_src[0]);
        $vt_image = array(
            'url' => $new_img,
            'width' => $image_detail['width'],
            'height' => $image_detail['height']
        );
        return $vt_image;
    }
    // default output - without resizing
    $vt_image = array(
        'url' => $image_src[0],
        'width' => $image_src[1],
        'height' => $image_src[2]
    );
    return $vt_image;
}
?>
.

  • ответить
Аватар пользователя Григорий
Григорий
Опубликовано 26.02.2015

Cпасибо большое, так гораздо проще

  • ответить
Аватар пользователя andrei
andrei
Опубликовано 26.02.2015

спасибо за статью. очень пригодился ваш класс

  • ответить
Аватар пользователя Denis
Denis
Опубликовано 29.04.2015

Не работает с большими изображениями (с цифровика)

  • ответить
Аватар пользователя Александр
Александр
Опубликовано 3.07.2015

Покажите реализацию данного класса

  • ответить
Аватар пользователя Александр
Александр
Опубликовано 3.07.2015

header('Content-Type: image/gif');
   include('classSimpleImage.php');
   $image = new SimpleImage();
   $image->load('101_183.gif');
   $image->resizeToWidth(150);
   $image->output();

это код выводит:

не может быть показано, так как содержит ошибки

если использовать:

header('Content-Type: image/gif');
readFile("101_183.gif");

то все нормально, но как добавляешь include и вписываешь код выше, так сразу выдает ошибку

  • ответить
Аватар пользователя GTAlex.ru
GTAlex.ru
Опубликовано 7.07.2015

Прозрачность в png делает чёрным :(

  • ответить
Аватар пользователя Станислав
Станислав
Опубликовано 9.08.2015

Изумительно ... Просто восхитительно !!! Спасибо огромное !!!

  • ответить
Аватар пользователя mr_0wl
mr_0wl
Опубликовано 14.09.2015

Как мне указать путь куда сохранять изображения. К примеру: "../../photo-galery/min/qwerty.jpg"?

  • ответить
Аватар пользователя sun
sun
Опубликовано 2.02.2016

всё работает хорошо, но! фото начиная с 2 мегабайт не сжимает выдает ошибку

Warning: getimagesize() [function.getimagesize]: Filename cannot be empty in S:\home\localhost\www\up\classSimpleImage.php on line 28

Warning: imagesx() expects parameter 1 to be resource, null given in S:\home\localhost\www\up\classSimpleImage.php on line 60

Warning: Division by zero in S:\home\localhost\www\up\classSimpleImage.php on line 71

Warning: imagesy() expects parameter 1 to be resource, null given in S:\home\localhost\www\up\classSimpleImage.php on line 63

Warning: imagecreatetruecolor() [function.imagecreatetruecolor]: Invalid image dimensions in S:\home\localhost\www\up\classSimpleImage.php on line 81

Warning: imagesx() expects parameter 1 to be resource, null given in S:\home\localhost\www\up\classSimpleImage.php on line 60

Warning: imagesy() expects parameter 1 to be resource, null given in S:\home\localhost\www\up\classSimpleImage.php on line 63

Warning: imagecopyresampled() expects parameter 1 to be resource, boolean given in S:\home\localhost\www\up\classSimpleImage.php on line 82

Warning: imagejpeg() expects parameter 1 to be resource, boolean given in S:\home\localhost\www\up\classSimpleImage.php on line 40

а если изображение более 8 мб то:

Warning: POST Content-Length of 9373233 bytes exceeds the limit of 8388608 bytes in Unknown on line 0

как можно исправить то? хотябы чтобы до 4мб сжимала

  • ответить
Аватар пользователя фывфы
фывфы
Опубликовано 6.07.2016

Да просто в php.ini на сервере надо поменять лимит, если не ошибаюсь там как раз стоит 2Mb. У меня на apache все работает после того как лимит повысил.

  • ответить
Аватар пользователя Дмитрий
Дмитрий
Опубликовано 13.09.2016

Автор, спасибо за скрипт. пол дня проискал, ставил разные и все работали через одно место. Этот единственный без проблем заработал. И работает довольно быстро, так как я использую в цикле и сразу обрабатывается до 30 картинок.

  • ответить
Аватар пользователя Luceus
Luceus
Опубликовано 2.06.2017

Благодарю за полезную информацию. Очень качественный пост.
Мало знаю о PHP и был очень удивлён, что этот код у меня сразу сработал, без обычных головоломок и без кучи потерянного времени на их выяснение.

  • ответить
Аватар пользователя Aleh
Aleh
Опубликовано 19.10.2017

что-то не очень код срабатывает если открыть картинку в PNG и сохранять в JPEG он ее тупо сохраняет в PNG не смотрять на то что по умолчанию JPEG
В JPEG так и не удалось вывести. Ошибки.

  • ответить
Содержание этого поля является приватным и не предназначено к показу. Если у вас есть Gravatar аккаунт, связанный с введенным адресом email, то он будет использован для отображения вашего аватара.

Filtered HTML

  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешённые HTML-теги: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и параграфы переносятся автоматически.
  • Для публикации фрагментов кода, используйте тег <code>...</code>.

Категории блога

  • Drupal 7 (35)
  • Drupal 8 (1)
  • PHP (6)
  • jQuery (3)
  • Linux (6)
  • Интернет (1)
  • JavaScript (1)
  • Дизайн (1)
  • События (19)
  • Разное (1)

Архив блога

  • декабрь 2017 (1)
  • август 2017 (1)
  • июль 2017 (1)
  • июнь 2017 (1)
  • май 2017 (1)
  • апрель 2017 (1)
  • март 2017 (2)
  • сентябрь 2016 (2)
  • июнь 2016 (1)
  • январь 2016 (1)
  • сентябрь 2015 (2)
  • май 2015 (1)
  • февраль 2015 (3)
  • ноябрь 2014 (1)
  • октябрь 2014 (1)
  • сентябрь 2014 (1)
  • июль 2014 (1)
  • июнь 2014 (1)
  • май 2014 (1)
  • январь 2014 (1)
  • декабрь 2013 (3)
  • ноябрь 2013 (2)
  • сентябрь 2013 (2)
  • август 2013 (2)
  • июнь 2013 (3)
  • май 2013 (4)
  • апрель 2013 (2)
  • март 2013 (3)
  • февраль 2013 (1)
  • декабрь 2012 (3)

Связь с автором

Alex Schedrov Twitter Icon Alex Schedrov Facebook Icon Alex Schedrov Drupal Icon Alex Schedrov Github Alex Schedrov RSS Icon
© Schedrov Alexander, 2011—2021