Веб дневник

Стратулат Владислава

«Картинка по заказу»

Суббота, 30 Октября 2010, 19:37

Недавно при разработке интернет-проекта Student Travel, столкнулся с ситуацией в которой загружаемые изображения должны были отображаться в радужной рамке овальной формы.

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

Загружаемый оригинал Требуемый результат

Итак, приступим...

Учитывая что проект был разработан на Drupal, соответственно и описывать процесс я буду именно для него. Но при сильном желании, реализацию можно перенести и на другие системы.

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

Итак, нам необходимы модули ImageCache и ImageCache Actions. После того как мы их добавили в проект, необходимо включить следующие модули из группы ImageCache:

  1. ImageCache
  2. ImageCache UI
  3. ImageAPI
  4. ImageAPI GD2
  5. Imagecache Canvas Actions
  6. Imagecache Color Actions
  7. Imagecache Custom Actions

Далее, в разделе Dashboard » Site building » ImageCache добавляем новый шаблон и назовем его custom-image.

Первую обработку которую пройдет изображение - это изменение размеров. В моем примере изображение на выходе должно иметь 200×200 пикселей.

Шаг первый: добавляем Deprecated Scale, и делаем следующие настройки:

  1. Width указываем 200;
  2. Height указываем 200;
  3. Scale to fit выбираем Outside dimensions.

Scale to fit мы обязательно ставим на Outside dimensions, потому что если мы выберем Inside dimensions, то изображение по ширине или высоте обязательно будет меньше чем 200 пикселей требуемых нами, что соответственно уже не подходит нашей задаче.

Scale to fit = Outside dimensions
Результат: 200×232 пикселя
Scale to fit = Inside dimensions
Результат: 172×200 пикселя

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

Шаг второй: Crop, и его настройки:

  1. Width указываем 200;
  2. Height указываем 200;
  3. X offset указываем center.
  4. Y offset указываем center.

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

X offset = center, Y offset = center
Результат: изображение вырезано по центру
X offset = center, Y offset = top
Результат: изображение вырезано с верхнего края

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

К сожалению, PHP не имеет функции которая позволяла бы напрямую наложить маску на изображение. К счастью, я нашел реализацию предложенную неким «Тобиасом» на сайте PHP в комментариях функции imagesavealpha, которую я взял за основу для следующего шага.

Шаг третий: Custom action, или «Функция Тобиаса»:

В поле Cod мы помещаем следующий код:

// Создаем клон из уже имеющегося у нас изображения
$picture = $image->resource;

// Создаем маску из заранее приготовленного изображения
$mask = imagecreatefrompng('./images/custom-image-mask.png');

// Получаем размеры изображения и создаем новое
$xSize = imagesx($picture);
$ySize = imagesy($picture);
$newPicture = imagecreatetruecolor($xSize, $ySize);
imagesavealpha($newPicture, true);
imagefill($newPicture, 0, 0, imagecolorallocatealpha($newPicture, 0, 0, 0, 127));

// Выполняем по-пиксельную обработку изображения с применением маски
for ($x = 0; $x < $xSize; $x++) {
    for ($y = 0; $y < $ySize; $y++) {
        $alpha = imagecolorsforindex($mask, imagecolorat($mask, $x, $y));
        $alpha = 127 - floor($alpha['red'] / 2);
        $color = imagecolorsforindex($picture, imagecolorat($picture, $x, $y));
        imagesetpixel($newPicture, $x, $y, imagecolorallocatealpha($newPicture, $color['red'], $color['green'], $color['blue'], $alpha));
    }
}

// Обновляем изображение новым и удаляем клонированное
imagedestroy($picture);
$image->resource = $newPicture;
return $image;
Результат после обработки функцией «Тобиаса» Используемая маска

Как видно по изображению, места где маска была полностью черной, были удалены.

Результат нас полностью удовлетворил, но это еще не финал. Следующий этап это прикрепить радужную рамку.

Шаг четвертый: Overlay (watermark), и его настройки:

  1. X offset указываем 0;
  2. Y offset указываем 0;
  3. opacity указываем 100;
  4. file name указываем путь до файла с радужной рамкой. Файл обязательно должен быть в png формате с прозрачным фоном.
Результат после применения маски Используемая маска с рамкой

Вы подумаете что это все, но не торопитесь.

Шаг пятый: Change File format, или «png должен быть png»:

Есть большая вероятность что загружаемые изображения будут в формате jpg, gif и др., поэтому для того чтобы мы точно получили требуемый результат, сделаем так чтобы изображение в конечном счете было конвертировано в png формат. Для этого из списка File format выбираем png.

Мы выбираем png! ...а jpg используют...

А вот теперь пожалуй все.

Надеюсь данная статья поможет вам в дальнейших разработках.

Когда я двигаюсь...

Последние комментарии

Тематические ссылки