Сжимаем размер картинки на PHP. Обработчик картинок classSimpleImage.


Манипуляции с графикой на сайте часто доставляют разработчику немало проблем. Особенно актуальны вопросы загрузки пользовательских картинок на сервер. Например, у Вас сайт с тематикой ремонта, путешествий, народного творчества и т.п. там, где необходимо публиковать большое количество графики. Одно дело, когда картинки загружаются администратором для статьи или поста и её размеры, тип и вес заранее подогнаны для загрузки. Но, что делать, когда графика загружается в комментарии к статье, ведь подготавливать картинки перед загрузкой пользователь скорее всего не будет, а если попытаться мотивировать  предупреждающими сообщениями о формате, размере и весе файла, то зачастую писать комментарий вовсе передумает. Если же разрешить загрузку на сайт пользовательской графики, то вебмастеру нужно позаботься о:

  1. Достаточном месте на сервере для размещения графики.
  2. Достаточной для обработки графики процессорной мощности.
  3. Реализации динамической оптимизации загружаемого графического контента.

В первых двух пунктах всё в принципе решается выбором хостинг провайдера и лимитов тарифа. Читайте: «Какой выбрать хостинг

К процедуре оптимизации загружаемой на сервер графики можно отнести функции:

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

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

Для теста я ограничил размер картинки до 250px по высоте и ширине. А максимальный вес файла в 600кб. Теперь:

  • Если файл типа png или gif по габаритам меньше ограничений, то он запишется на сервер без трансформации. Если это jpg, то осуществиться компрессия файла, согласно качеству заданному в форме отправки.
  • Если файл по габаритам больше лимитного ограничения, то он будет вписан в установленные максимальные размеры, в Demo это 250px.
  • Если файл весит больше 600kb, то пользователь получит предупреждение о превышении лимита, а сам файл обрабатываться не будет.
  • И, наконец, если файл не проходит проверки или пришёл пустой запрос, то появится соответствующее предупреждение об отсутствии файла.

Для реализации поставленных задач был использован, обнаруженный на просторах интернета и немного мной доработанный, PHP класс «classSimpleImage.php» Скачать

В листинге ниже привожу комментированный код php принимающей стороны:

PHP
//Подключаем классclassSimpleImage
include_once('./classSimpleImage.php');
//Определяем протокол
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? "https://" : "http://";
//Вносим в массив разрешённые источники отправки
$accepted_origins = array("http://localhost", "http://192.168.1.1", "https://my-skills.ru");
//Производим проверки
  if (isset($_SERVER['HTTP_ORIGIN'])) {
    // запросы с одинаковым источником не будут устанавливать источник. Если источник установлен, он должен быть действительным.
    if (in_array($_SERVER['HTTP_ORIGIN'], $accepted_origins)) {
      //Заголовки если принимать через ajax
      //header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); return;
      $flag = true;
    } else {
      //header("HTTP/1.1 403 Origin Denied");  return;
      $flag = false;
    }
  }
    // Не пытайтесь обработать загрузку по запросу OPTIONS.
  if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    //header("Access-Control-Allow-Methods: POST, OPTIONS");  return;
     
  }
  if (is_uploaded_file($_FILES['userimg']['tmp_name']) and $flag === true) {
     //Получаем параметры качества
     $compession = trim(strip_tags($_POST['compression'])) * 1;
     //Путь к папке загрузки
     $imageFolder = "./img/";
     reset ($_FILES);
     $temp = current($_FILES);
     // Sanitize input Очистить ввод
     if (preg_match("/([^wsd-_~,;:[]().])|([.]{2,})/", $temp['name'])) {
        header("HTTP/1.1 400 Invalid file name.");  return;
        //В Demo я не провожу эту проверку на соответствие имени файла
        //$flag = false;
     }
     // Проверить расширение
     if (!in_array(strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION)), array("gif", "jpg", "png"))) {
        //header("HTTP/1.1 400 Invalid extension.");  return;
        $flag = false;
     }
  }
  if (is_uploaded_file($temp['tmp_name'])  and $flag === true){
    /*
      Если вашему сценарию необходимо получать файлы cookie, установите images_upload_credentials : true в
       конфигурацию и включите следующие два заголовка.
    */
    // header('Access-Control-Allow-Credentials: true');
    // header('P3P: CP="There is no P3P policy."');

    $tempsize = $temp["size"].' Байт ';//Размер получаемого файла
    //Проверяем на превышение размера 600kb
    if($temp["size"] > 600000){
        //Картинка предупреждение "MAX SIZE IMG"
        $imgurl = "img/max-size-img-250.png";
    }else{
    // Принять загрузку, если не было источника или если это принятый источник
    $ext = mb_strtolower(mb_substr(mb_strrchr($temp['name'], '.'), 1));
    $filetowrite = $imageFolder . 'demo-45.'.$ext;
    $imgurl = 'img/demo-45.'.$ext;
    list($width, $height) = getimagesize($temp['tmp_name']);
    $nwh = 250;
    if (($width >= $nwh) || ($height >= $nwh)) {
        if($width > $height){
            $rez = $nwh * 100 / $width;
        }else{ $rez = $nwh * 100 / $height;}
       // Класс для сжатия графики
       $image = new SimpleImage();
       //Загружаем исходную картинку
       $image->load($temp['tmp_name']);
       //Трансформируем
       $image->scale($rez);
       //Запись в папку + компрессия
       $image->save($filetowrite, exif_imagetype($temp['tmp_name']), $compession);
    }else{
       //Запись без трансформации
       $image->save($filetowrite, exif_imagetype($temp['tmp_name']), $compession);
    }
    }

  } else {
    //Картинка предупреждение "NO IMAGES"
    $imgurl = 'img/no-images-240.png';
  }

 Класс classSimpleImage.php

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=40, $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);
     //Отключаем режим сопряжения цветов
      imagealphablending($new_image, false);
     //Включаем сохранение альфа канала
      imagesavealpha($new_image, true);
      imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
      $this->image = $new_image;
   }
}

 

Дата публикации: 

ТОП 10 случайных публикаций



Сайт разработан студией © WEB-VidST   


Яндекс.Метрика