
<?php
// Указываем картинку, которая будет фоном по умолчанию
$background = 'assets/images/preview_bg.png';
// Получаем ID ресурса и текст для надписи
$id = $input;
$pagetitle = $options;
if (!$id) {
$id = $modx->resource->id;
}
if (!$resource = $modx->getObject('modResource', $id)) {
return;
}
if (!$pagetitle) {
$pagetitle = $resource->menutitle ?: $resource->pagetitle;
}
// Создаём папки для превьюшек
$path = $modx->getOption('base_path') . 'assets/images/';
if (!file_exists($path)) mkdir($path);
$path .= 'previews/';
if (!file_exists($path)) mkdir($path);
$path .= $id . '/';
if (!file_exists($path)) mkdir($path);
$output = $path;
// Если к ресурсу прикреплено изображение, используем его имя
if ($resource->getTVValue('img')) {
$tmp = explode('.', basename($resource->getTVValue('img')));
array_pop($tmp);
$name = implode('.', $tmp);
$output .= $name;
// и устанавливаем его в качестве фона
$background = $resource->getTVValue('img');
} else {
// а если нет - то название картинки будет preview.png
$output .= 'preview';
}
// Добавляем хеш надписи в имя картинки
$output .= '-' . substr(md5($pagetitle), 0, 3);
// И расширение png
$output .= '.png';
// Проверяем, что такое изображение мы ещё не генерировали
if (!file_exists($output) || true) {
// Переносим текст по строчкам
$pagetitle = rtrim($pagetitle);
$length = 27;
$words = explode(' ', $pagetitle);
$pagetitle = '';
$actual = '';
foreach ($words as $word) {
if (mb_strlen($actual.$word) <= $length)
$actual .= $word.' ';
else {
if ($actual != '')
$pagetitle .= rtrim($actual).'|';
$actual = $word;
$actual .= ' ';
}
}
$pagetitle .= trim($actual);
$rows = explode("|", $pagetitle);
$draw = new \ImagickDraw();
$outputImage = new \Imagick($modx->getOption('base_path') . $background);
// Подготавливаем фоновую картинку
$width = 800;
$height = 600;
$cropWidth = $outputImage->getImageWidth();
$cropHeight = $outputImage->getImageHeight();
// Если фоновая картинка маловата, пишем сообщение в лог
if ($cropWidth < $width || $cropHeight < $height) {
$modx->log(1, "[getPreview] Background image for resource {$id} is small");
return;
}
// Приводим картинку к соответствующим пропорциям
if ($cropHeight < $height * $cropWidth / $width) {
$newWidth = $cropHeight * $width / $height;
$outputImage->cropimage($newWidth, $cropHeight);
} else {
$newHeight = $cropWidth * $height / $width;
$outputImage->cropimage($cropWidth, $newHeight);
}
// И уменьшаем до нужных размеров
$outputImage->scaleImage($width, $height);
// Рисуем закрашенный полупрозрачный прямоугольник
$draw->setFillColor('#00669966');
$points = [
['x' => 25, 'y' => 40],
['x' => $width - 25, 'y' => 40],
['x' => $width - 25, 'y' => 60 + 65 * count($rows)],
['x' => 25, 'y' => 60 + 65 * count($rows)],
];
$draw->polygon($points);
$outputImage->drawImage($draw);
// Устанавливаем параметры текста
$draw->setStrokeWidth(0);
// Нужно загрузить файл шрифта на сервер
$draw->setFont($modx->getOption('base_path') . 'fonts/RobotoSlab-Bold.ttf');
$draw->setFontSize(45);
$draw->setGravity(\Imagick::GRAVITY_NORTHWEST);
$draw->setTextAntialias(true);
// Рисуем сначала тень текста
$draw->setStrokeColor('#00000030');
$draw->setFillColor('#00000030');
$y = 55; $x = 50;
foreach ($rows as $row) {
$outputImage->annotateImage($draw, $x, $y, 0, $row);
$y += 65;
}
// Потом сам текст поверх тени
$draw->setStrokeColor('#fff');
$draw->setFillColor('#fff');
$y = 50; $x = 45;
foreach ($rows as $row) {
$outputImage->annotateImage($draw, $x, $y, 0, $row);
$y += 65;
}
// И сохраняем картинку
$outputImage->setImageFormat('png');
$outputImage->writeimage($output);
}
// Обрезаем путь от корня сервера
$output = str_replace($modx->getOption('base_path'), '/', $output);
// и выводим адрес картинки
return $output;На сервер должен быть установлен ImageMagick.
Объектная
PS: не на тот уровень, сори
Ответил за Илью )
В любом случае, полезный скрипт. Найдет свое применение :)
И еще там где рисуется полупрозрачный прямоугольник — надо либо через плейсхолдер, либо внутри снипета указать путь к файлу png, который наляпывается поверх нашей пикчи?
Спасибо!