Работа с phpThumb


Не многие задумывались, что вместе с MODX Revolution поставляется и phpThumb. Это, фактически, единственная и самая крутая библиотека для работы с изображениями на PHP.

В MODX принято работать с ней через сниппет phpThumbOf, однако у него есть существенные недостатки, например серьёзные тормоза и странное кэширование. Поэтому, верным способом будет работа с библиотекой напрямую.

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

Заодно решил известную проблему с генерацией уменьшенной копии, с обрезкой из левой верхней части картинки.

Запуск phpThumb


Предлагаю универсальный скрипт, который может запускаться как снаружи MODX, так и в качестве сниппета.
<?php
if (!isset($modx)) {
	define('MODX_API_MODE', true);
	require 'index.php';	// Если запускаем снаружи - тут надо указать путь к файлу в корне сайта

	$modx->getService('error','error.modError');
	$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
	$modx->setLogTarget('FILE');
}

$src = MODX_BASE_PATH.'img.jpg';	// Исходник
$dst = MODX_BASE_PATH.'img_thumb.jpg';	// Уменьшенная копия

$params = array(
	'w' => 300	,		// Ширина
	'h' => 176,		// Высота
	'bg' => 'ffffff',		// Фон
	'q' => 95,			// Качество в %
	'zc' => 'TL',		// Обрезка, TL - это Top Left, есть еще C - center, BR - Bootom Right  и т.д.
	'f' => 'jpg',		// Формат изображения
);

// Подключаем обёртку MODX, которая выставит системные настройки в класс phpThumb
$phpThumb = $modx->getService('modphpthumb','modPhpThumb', MODX_CORE_PATH . 'model/phpthumb/', array());

// Указываем исходник
$phpThumb->setSourceFilename($src);

// Выставляем параметры
foreach ($params as $k => $v) {
	$phpThumb->setParameter($k, $v);
}

// Генерируем уменьшенную копию
if ($phpThumb->GenerateThumbnail()) {
	// Выводим готовое изображение сразу на экран
	//return $phpThumb->OutputThumbnail();
	
	// Или сохраняем в файл
	if (!$phpThumb->renderToFile($dst)) {
		$modx->log(modX::LOG_LEVEL_ERROR, 'Could not save rendered image to'.$dst);
	}
}
else {
	// Если возникла ошибка - пишем лог работы в журнал MODX
	$modx->log(modX::LOG_LEVEL_ERROR, print_r($phpThumb->debugmessages, 1));
}
Этот скрипт прекрасно работает, обрезает и уменьшает изображения за исключением одного момента — обрезка идёт всегда по центру рисунка. Причем, зависит это не от phpThumb, а от сервера.

ImageMagick


phpThumb сам не умеет конвертировать изображения, он запускает один из модулей PHP: phpGD2 или ImageMagick.

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

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

Устанавливаем его на сервер, настроенный по этой заметке:
sudo apt-get install imagemagick php5-imagick
Перезапускаем php5-fpm:
sudo service php5-fpm restart
Смотрим в phpinfo(), что ImageMagick подключен.

Проверяем работу скрипта и ничего не меняется!

А дело в том, что на моём сервере (и многих других) отключены функции exec, system, shell_exec и passthru, через которые phpThumb пытается выяснить версию установленного ImageMagick, а потом и запустить его на конвертацию.

Понять это можно, если поглядеть в лог работы:
[2013-01-27 10:50:30] (ERROR @ /test.php) Array
(
    [0] => phpThumb() v1.7.9-200712090829 in file "phpthumb.class.php" on line 216
    [1] => setSourceFilename(/var/www/static/www/img.jpg) set $this->sourceFilename to "/var/www/mysite/www/img.jpg" in file "phpthumb.class.php" on line 243
    [2] =>   file_exists() = 0 in file "phpthumb.class.php" on line 1101
    [3] => is_executable() = 0 in file "phpthumb.class.php" on line 1102
    [4] => ImageMagickThumbnailToGD() aborting because cannot find convert in $this->config_imagemagick_path (), and `which convert` returned () in file "phpthumb.class.php" on line 1131
    [5] => $AvailableImageOutputFormats = array(text;ico;bmp;wbmp;gif;png;jpeg) in file "phpthumb.class.php" on line 884
ImageMagickThumbnailToGD() aborting выглядит нехорошо, правда?

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

Результат работы phpThumb с параметром zc = TL:
  • Модуль phpGD2
  • Модуль ImageMagick
Не забывайте, что всегда можно проверить, какой способ используется в логе $phpThumb->debugmessages.
Василий Наумкин
27 января 2013, 07:00
modx.pro
25
29 917
0

Комментарии: 17

СикретНаме
31 января 2013, 12:58
0
1. Я так понимаю, что на обычном виртуальном сервере функцию не включить?
2. ThumbOf иThumb чем существенно различаются, что-то не нашёл в Рунете?
    Василий Наумкин
    31 января 2013, 13:13
    0
    Надо смотреть на хостинг, далеко не везде их вообще отключают.

    phpThumb — библиотека для работы с изображениями.
    phpThumbOf — сниппет MODX для ресайза и кэша изображений с помощью phpThumb.
    Aliaksandr Katlou
    07 февраля 2013, 15:30
    0
    Скрипт очень приятный и удобный. Но есть пичаль, про которую я уже как-то тему создавал, но еще тут на всякий случай спрошу. Ни скрипт ни phpthumbof хочет сохранять миниатюру с ошибкой —
    (ERROR @ /index.php) Could not save rendered image to/hosting2/bikes/public_html/images/MY13_HP_road_report_v1.thumb.jpg
    Права на каталог 777, и все идеи куда копать у меня кончились(

    Файл создается, но пустой.
      Василий Наумкин
      07 февраля 2013, 15:33
      0
      А если туда же попробовать file_put_contents()?

      100% с правами что-то.
      Aliaksandr Katlou
      07 февраля 2013, 15:49
      0
      Туда же тоже не хочет(

      Придется хостинг менять.
      Aliaksandr Katlou
      07 февраля 2013, 16:12
      0
      Спасибо за ссылку, но переду на hoster.by — у меня там с десяток сайтов разных хостится и ни разу никакаих проблем. А с остальными хостингами в зоне бай — постоянные и всегда в самый не подходящий момент. Так что ну его нафиг. Не картинки так еще что-нибудь потом вылезет.

      Есть еще Active.by — вообще отдельная история, там стоит хоститься только если ты любишь латексные костюмы, боль и удары плетки — отличным дополнением станет) Кстати, там в антихостинг его можно смело добавлять — медленный, с отвратительной панелью, корявой поддержкой и страшными глюками с половиной компонентов и особенно с картинками.
        Andrei Kulazhenko
        07 февраля 2013, 16:43
        0
        Лично у меня проблем с Active.by особенных никогда не было. Единственное, что я делаю, прописываю в htaccess следующие правила:

        #active.by instructions
        php_flag eaccelerator.enable 0
        php_flag eaccelerator.optimizer 0
        SetEnv force-response-1.0 1
        SetEnv downgrade-1.0 1
        + у Active отличная техподдержка, чего я, при всем желании и уважении, не могу сказать о саппорте тутбаевского hoster.by. Хотя у hoster.by — вполне вменяемый и нормальный рабочий виртуальный хостинг. В общем, это вопрос личного выбора. Но active.by я бы точно не заносил в черный список.
          Aliaksandr Katlou
          07 февраля 2013, 17:37
          0
          Может конечно мне одному так не повезло)
            Aliaksandr Katlou
            07 февраля 2013, 17:49
            0
            Тем не менее, полгода назад имело место — частично не работающая основная панель управления active.by (в частности что касается переноса домена). Панель управления хостингом — ipsmanager, крайне мне не удобный. Поддержка тупила.
              Жуковский Антон
              07 февраля 2013, 19:36
              0
              Мне, выходит, повезло. За год ни разу не обращался в поддержку. С проблемой картинок тоже столкнулся, но быстро нашел на modx.com совет отключить eaccelerator. Админка Revo, кстати, просто летает.
              Жуткую панель управления обновили. Так что буду продлевать еще на год и купил подписку на activecloud.ru (то же самое, только в РФ), чтобы перенести российские сайты. Дополнительный плюс — партнерка, для РФ можно 50% стоимости компенсировать. SSH опять же бесплатный.
                Василий Наумкин
                07 февраля 2013, 20:47
                0
                Linode платит $ 20 за каждого реферала, который пользуется их услугами 3 месяца.

                Ну это я так, к слову.
              Владимир
              11 июля 2013, 23:39
              0
              Доброго дня! Василий, ведь у тебя размещены сайты в том числе на Timeweb (сайт о фитнесе, как я помню ты упоминал его в данном блоге ).
              На хостинге Таймвеб судя по php info:
              imagick module enabled
              imagick module version 3.0.1
              imagick classes Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator
              ImageMagick version ImageMagick 6.6.1-2 2010-07-06 Q16 www.imagemagick.org
              Т.е. должно все работать без проблем? Не сталкивался с работой ImageMagick именно на Timeweb?
              Спасибо.
              PS Вот то же решение предлагается www.darkstardesign.com/resources/phpthumbsup и то же для ресайза ImageMagick используется.
                Володя
                12 июля 2013, 00:27
                0
                у меня помню проблема была на timeweb заставить обрабатывать картинки через GD2. Так что на timeweb Imagick работает… все нормально
                  Василий Наумкин
                  12 июля 2013, 03:14
                  0
                  Не сталкивался.

                  Если там есть ImageMagick, и доступ к нему из консоли — всё должно работать нормально.
                  Boris Akimenko
                  12 июля 2013, 16:26
                  0
                  Василий, для меня очень актуальна тема генерации PNG c прозрачным фоном в минишоп-2.
                  На хостинге можно штатными средствами подключить imagic (отметить чекбокс :) ).
                  Что и как нужно изменить в настройках, чтобы генерились PNG с прозрачным фоном? Исходные изображения, разумеется, тоже с прозрачным фоном загружаю.
                  Спасибо!
                    Илья Уткин
                    01 марта 2017, 14:06
                    0
                    Для тех, кто не хочет включать эти опасные функции, нашёл небольшой костыль. Нужно в файле core/model/phpthumb/phpthumb.class.php в методе ImageMagickVersion поменять последнюю строчку (у меня это 1499 строчка файла) на слудующее:

                    return '6.4.9'; //$versionstring[intval($returnRAW)];

                    Здесь мы вне зависимости от того, получилось ли определить версию imageMagick или нет, выводим фейковое значение.
                      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                      17