<?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, который наляпывается поверх нашей пикчи?
Спасибо!