четверг, 5 мая 2011 г.

PHP: Класс ucResizeImg v2.0, универсальный алгоритм ресайза изображений

Первоначально приветствую вас и надеюсь вы не потратите время зря. Следующий модуль я создавал первоначально для себя, стараясь покрыть все возможные тривиальные (может некоторые и не совсем тривиальные) задачи, касательно резайзинга изображений на серверной стороне. Но также хочу поделиться со всеми своим трудом, поскольку прошлая версия этого модуля, намного менее совершенная, получила резонанс, и пришлась очень кстати многим. Это был файл, содержащий 2-е функции: http://dev.1c-bitrix.ru/community/webdev/user/25535/blog/1446/

По советам потребителей прошлой версии, я объединил эти 2-е функции в одну, если так можно сказать. Я создал класс, существенно расширив функционал и универсальность, также используя более дружелюбную параметризацию. 1С-Битрикс режим теперь включён внутрь класса, нужно только активировать его, в то время как в прошлой версии — это были два отдельных скрипта. Обо всех изменениях думаю рассказывать сейчас не стоит, ибо скорее всего вы видите этот модуль впервые, лучше я расскажу о каждой возможности отдельно. Да и по-моему эту версию и прошлую уже можно считать двумя разными не связанными между собой скриптами.

Возможности модуля:
  • Получение отрезайзеного изображения;
  • Поддержка форматов: JPEG, PNG, GIF (выходящий файл всегда JPEG);
  • Кеширование выходящих файлов;
  • Гибкая и универсальная параметризация;
  • Совместимость с 1С-Битрикс;
  • Возможность выдавать строгие размеры изображения;
  • Имеется режим отладки.


Кстати хочу отметить — на всякий случай прокомментировал скрипт, чтобы его можно было применять, каждый раз не обращаясь к данному материалу. Прокомментировал на английском языке (мало ли кто будет пользоваться :), конечно знания мои неидеальны, мог излагаться неверно (мог и очень неверно). Теперь по порядку инструкция к применению:
  1. Изначально нужно скрипт подключить, я думаю как это делать описывать не особо нужно, но на всякий случай приведу пример, который может быть субъективен. Итак, положите файл скрипта вместе с тем файлом, в котором будете его подключать и можете вписать следующий код для подключения:
    <?php require_once 'ucresizeimg.class.v2.0.php'; ?> 

    Как вы уже поняли (если поняли), этот модуль является классом и количество его экземпляров со своими индивидуальными параметрами теоретически — неограниченно. По умолчанию уже имеется один экземпляр класса, доступный под переменной $ucResizeImg, но вы без проблем можете создать новый экземпляр следующим образом:
    <?php $example = new C_ucResizeImg; ?>

    Если же вы не имеете представлений о том, что такое ООП, то не беспокойтесь, модуль будет работать без лишних манипуляций, если вы будете следовать инструкции;

  2. Далее мы сразу рассмотрим 1С-Битрикс режим, если вы не используете 1С-Битрикс, исключите из своего сознания существование пункта №2. Если вы читаете дальше, то специально для вас поясняю для чего это нужно — это нужно для корректной работы многосайтовости, когда один из сайтов направлен на папку глубже корня. Если многосайтовости у вас нет, то можете тоже вычеркнуть пункт №2, если есть, то рекомендую включить, я особо не тестировал, но сделал всё по логике, если будут баги — прошу, сообщайте. Включить Битрикс-режим можно следующим образом:
    <?php $ucResizeImg->SetDefParams(array('BITRIX_MODE'=>true)); ?> 

  3. Ещё одно пояснение для использующих 1С-Битрикс: для подключения я рекомендую класть файл в папку: /bitrix/php_interface/#SITE_ID#/ и подключать скрипт в файле этой же папки: init.php, если нет этих папок или файла — создайте. #SITE_ID# — это идентификатор сайта (обычно s1);
     
  4. Рассмотрим для начала список функций:
    • GetResized — производит ресайз файла, кеширует его и возвращает путь до файла, содержащего новое отресайзеное изображение;
    • SetDefParams — задаёт массив параметров по умолчанию;
    • GetDefParams — возвращает массив текущих параметров по умолчанию.

    • Опишем принцип параметризации для GetResized и SetDefParams: всего одним параметром указывается массив с набором — ключ-значение. Для GetResized есть некое исключение, если этот один параметр является строкой, то он его воспринимает как путь до входящего файла, который подлежит ресайзу и в остальном использует параметры по умолчанию. В скрипте уже есть стандартный набор параметров со стандартными значениями, при указании параметров указывайте только те, которые хотите изменить, остальные присоединятся автоматически.
       
    • Далее я опишу каждый параметр передаваемого массива с его значением по умолчанию, а после, в следующем пункте приведу несколько примеров.
      array(
          # Путь до входящего файла от корня сайта
          'INPUT_FILE' => '',
      
          # CLASSIC: стандартный режим ресайза, границы выходящего изображения не превышают указанной ширины и высоты
          # STRONG: возвращаемое изображение будет строгих размеров и остаточная часть будет отрезана в соответствии с параметрами CONTENT_ZONE_X(Y)
          'RESIZE_MODE' => 'CLASSIC',
      
          # Если вы используете режим STRONG, то есть смысл использовать этот параметр
          # При режиме STRONG изображение ресайзится так, чтобы полностью заполнить указанные размеры
          # А та часть, что останется за пределами этих размеров, будет обрезана
          # И в следующих параметрах вам нужно указать какую часть изображения вам нужно захватить.
          # По оси X: LEFT CENTER RIGHT
          # По оси Y: TOP CENTER BOTTOM
          'CONTENT_ZONE_X' => 'CENTER',
          'CONTENT_ZONE_Y' => 'CENTER',
      
          # Сохранять размеры в случае, если одна из указанных сторон больше, чем в исходящем файле
          # Если этот параметр включен, то пустая часть будет заполнена цветом из параметра FILL_COLOR
          'KEEP_SIZE' => false,
      
          # Вот собственно 1С-Битрикс режим, о котором было рассказано выше
          'BITRIX_MODE' => false,
      
          # Если оба параметра указаны как ноль, то вы получите JPEG-файл без изменений размеров изображения
          # Если только один из параметров указан нулём, то по этой стороне размер будет неограничен, будет учитываться ограничение только по одной из сторон
          'WIDTH' => 0,
          'HEIGHT' => 0,
      
          # Качество выходящего JPEG-изображения (используется для экономии места)
          # Значение указывается от 0 до 100
          'QUALITY' => 85,
      
          # Путь до места сохранения выходящих изображений от корня сайта
          # Тут будет создана директория _thumbs (если уже не существует) для складирования там выходящих файлов
          # Если какая-то или несколько из директорий в пути не будут существовать, они будут созданы автоматически
          'PATH_TO_SAVE' => '',
      
          # Если выключить кеширование, то будет проверяться наличие выходящего файла и производиться его удаление перед повторным созданием
          'CACHE' => true,
      
          # Если выключить этот параметр, то папка _thumbs не будет создаваться и файлы будут складировать прямо в директорию указанную в параметре PATH_TO_SAVE
          # Также вы можете указать значение строкой и тогда вместо _thumbs будет создаваться директория с этим именем
          'CREATE_SUBFOLDER' => true,
      
          # Вы можете включить этот параметр и тогда у имени всех выходящих файлов будет префикс thumb_
          # Или можете указать значение строкой и префикс файлов будет таков, как в этом значении
          'FILE_PREFIX' => false,
      
          # Если вы включите этот параметр, то функция GetResized будет возвращать не просто путь до файла, а следующий массив значений:
          # 'OUTPUT_FILE' => (string)$PATH_TO_RESIZED_FILE, # путь до выходящего файла
          # 'WIDTH' => (int)$RESIZED_FILE_WIDTH, # ширина выходящего изображения
          # 'HEIGHT' => (int)$RESIZED_FILE_HEIGHT, # высота выходящего изображения
          # 'FILE_SIZE' => (int)$BYTES_OF_RESIZED_FILE, # размер выходящего файла в байтах
          # используя этот параметр вы можете задавать ширину и высоту для тега <img>
          'RETURN_COMPLEX' => false,
      
          # Режим отладки, полезная вещь, если идёт что-то не так
          # Если просто включить, то будет создаваться изображение с текстом ошибки
          # Если задать значение как текст 'TEXT', то будет возвращаться текст ошибки вместо пути до выходящего файла
          # Если режим отладки выключен, то при ошибке будет возвращаться строка 'error' вместо пути до выходящего файла
          # Ошибки будут отслеживаться на каждом этапе:
          # Ошибка входящих параметров, создание папки, определение типа файла, ошибка удаления файла при выключенном кешировании и прочее.
          'DEBUG' => false,
      
          # И последний параметр, заливка фона изображения
          # Задаётся как массив уровня цвета Red Green Blue, каждый от 0 до 255 (по умолчанию цвет белый)
          # Имеет смысл использовать, если включен параметр KEEP_SIZE
          'FILL_COLOR' => array(
              'R' => 255,
              'G' => 255,
              'B' => 255,
          ),
      )

    • А теперь практика, несколько примеров: возьмём для начала фото котэ вертикальное изображение и произведём с ним несколько манипуляций, для того, чтобы на деле показать, как работать с модулем:


      Для начала возьмём самый простейший пример:
      <img src="<?php echo $ucResizeImg->GetResized(array(
          'INPUT_FILE' => 'kote.jpg',
          'WIDTH' => 120,
          'HEIGHT' => 100,
      )); ?>">


      Теперь прыгнем вперёд и рассмотрим пример задания параметров по умолчанию, а также сохранение указанных размеров изображения и заливки пустот фоном:
      <?php $ucResizeImg->SetDefParams(array(
          'KEEP_SIZE' => true,
          'FILL_COLOR' => array('R'=>255,'G'=>0,'B'=>0), # Красный цвет
      )); ?>
      <img src="<?php echo $ucResizeImg->GetResized(array(
          'INPUT_FILE' => 'kote.jpg',
          'WIDTH' => 120,
          'HEIGHT' => 100,
      )); ?>">


      Теперь рассмотрим последний пример, надеюсь я исчерпаю на этом основные вопросы. На этот раз мы зададим режим STRONG, чтобы изображение подгонялось строго под указанные размеры, этот приём очень полезен при трепетных дизайнерских приёмах, в которых нужно строго соблюдать линии контента. Также мы будем использовать параметр RETURN_COMPLEX, чтобы указать тегу <img> ширину и высоту:
      <?php $rszImg = $ucResizeImg->GetResized(array(
          'INPUT_FILE' => 'kote.jpg',
          'WIDTH' => 120,
          'HEIGHT' => 100,
          'RESIZE_MODE' => 'STRONG',
          'RETURN_COMPLEX' => true,
      )); ?>
      <img src="<?php echo $rszImg['OUTPUT_FILE']; ?>" width="<?php echo $rszImg['WIDTH']; ?>" height="<?php echo $rszImg['HEIGHT']; ?>">
      <?php unset($rszImg); ?>

      Это был последний пример, но я не хочу упустить из виду важный параметр CONTENT_ZONE_X(Y), добавьте следующую строчку к параметрам:
      'CONTENT_ZONE_Y' => 'BOTTOM',
      И вот что мы получаем в итоге:
       
    Надеюсь теперь вы сможете без проблем пользоваться этой штукой, и да облегчит это вам жизнь!

    Скачиваем отсюда: http://lotsmanov-va.narod.ru/files/ucresizeimg.class.v2.0.zip

    Прошу, об ошибках, пожеланиях по доработке в новых версиях и прочему — пишите на почту, указанную внутри файла скрипта или в комментариях.

    UPD 2011/05/06: Внезапно обнаружилось в Битриксе недосягаемость переменной $ucResizeImg, чтобы дотянуться до переменной — нужно обращаться в глобальной зоне. Так что вместо $ucResizeImg пишите: $GLOBALS['ucResizeImg']. Вот пример:
    <img src="<?php echo $GLOBALS['ucResizeImg']->GetResized(array(
        'INPUT_FILE' => 'kote.jpg',
        'WIDTH' => 120,
        'HEIGHT' => 100,
    )); ?>">

        1 комментарий:

        1. Отлично!!!
          То что надо. Искал подобное два дня все не то, а тут все подробно и спасибо автору!

          ОтветитьУдалить