При копировании материалов, ссылка на источник ОБЯЗАТЕЛЬНА!!!

пятница, 19 октября 2012 г.

Применяем различные эффекты к фото с помощью PHP + GD

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

Для просмотра результатов выполнения скриптов php я решил взять фото знаменитого актера, сыгравшего Шерлока Холмса в одноименном фильме, а также Тони Старка в «Железном человеке» – Роберта Дауни младшего (Robert Downey Jr).

robert downey jr

Не стоит сильно критиковать реализацию эффектов, данные примеры взяты в ознакомительных целях, некоторые искал на различных форумах, некоторые придумывал сам.

Негатив
Здесь использовал стандартный (присутствующий в библиотеке) функционал – применил фильтр IMG_FILTER_NEGATE:
   header("Content-type: image/jpeg"); 
   $uploadfile = 'image.jpg';
   $source = imagecreatefromjpeg($uploadfile);
   imagefilter($source, IMG_FILTER_NEGATE);
   imagejpeg($source);
Как видно, переменной $uploadfile мы присваиваем путь к нашему изображению (image.jpg), потом на его основе создаем изображение, применяем к нему фильтр и отображаем в браузере, предварительно прописав в начале header("Content-type: image/jpeg"). Посмотрим полученный результат:

Негатив

Градация серого
Здесь тоже не надо придумывать ничего сложного, аналогично применяем подобный фильтр - IMG_FILTER_GRAYSCALE:
   header("Content-type: image/jpeg"); 
   $uploadfile = 'image.jpg';
   $source = imagecreatefromjpeg($uploadfile);
   imagefilter($source, IMG_FILTER_GRAYSCALE);
   imagejpeg($source);
В результате получаем:

Градация серого

Легкая сепия
Есть множество вариантов реализовать сепию, но когда-то я нашел в сети такой:
   header("Content-type: image/jpeg"); 
   $uploadfile = 'image.jpg';
   $source = imagecreatefromjpeg($uploadfile);
   imagefilter($source, IMG_FILTER_GRAYSCALE);
   imagefilter($source, IMG_FILTER_COLORIZE, 100, 70, 50);
   imagejpeg($source); 
То есть, мы применяем сначала фильтр «Градация серого» (IMG_FILTER_GRAYSCALE), а потом, с помощью еще одного фильтра (IMG_FILTER_COLORIZE), налаживаем цвет с такими значениями каналов: R=100, B=70, G=50.

Сепия

Эффект рисунка
Интересный эффект, которого тоже легко добиться, просто применив два фильтра: IMG_FILTER_MEAN_REMOVAL и IMG_FILTER_GAUSSIAN_BLUR.
   header("Content-type: image/jpeg"); 
   $uploadfile = 'image.jpg';
   $source = imagecreatefromjpeg($uploadfile);
   imagefilter($source, IMG_FILTER_MEAN_REMOVAL);
   imagefilter($source, IMG_FILTER_GAUSSIAN_BLUR);
   imagejpeg($source);
А вот и результирующая картинка данного кода:

Эффект рисунка

Рельефное фото
Такого эффекта легко можно достичь при использовании фильтра IMG_FILTER_EMBOSS.
   header("Content-type: image/jpeg"); 
   $uploadfile = 'image.jpg';
   $source = imagecreatefromjpeg($uploadfile);
   imagefilter($source, IMG_FILTER_EMBOSS);
   imagejpeg($source);
Видно, что в нашем коде, в принципе, меняются только названия фильтров, или их количество, но результат, естественно, очень сильно отличается :D

Рельефное фото

Зеркало
А это одно из моих сочинений… :) Здесь я выполняю такие действия:
  1. Создаю новое изображение truecolor с размерами нашей картинки-оригинала
  2. Запускаю цикл, а в нем еще и вложенный, для перебора каждого пикселя оригинальной картинки.
  3. В цикле получаю цвет текущего пикселя и устанавливаю его для пикселя созданного truecolor-изображения, но с обратной стороны. То есть, если я получаю цвет пикселя, например, второго слева и пятого сверху, то его я устанавливаю для пятого сверху, но уже второго справа. 
   header("Content-type: image/jpeg"); 
   $uploadfile = 'image.jpg';
   $source = imagecreatefromjpeg($uploadfile);
   $size = getimagesize($uploadfile);
   $result_source = imagecreatetruecolor($size[0], $size[1]);
   for ($x = 0; $x < $size[0]; $x++) {
    for ($y = 0; $y < $size[1]; $y++) {
    $color=imagecolorat($source, $x,$y);
    imagesetpixel($result_source, $size[0]-1-$x, $y, $color);
    }
   }
   imagejpeg($result_source);
Таким образом, я отобразил фото зеркально:

Зеркальное фото

Данный код может долго отрабатываться, особенно если изображение-оригинал большого расширения, но, повторюсь, я не ставил задачу написать оптимальный код на все случаи жизни. Это только вариант реализации зеркального отображения фото.

Черное и белое
Когда-то в интернете встречал алгоритм, как создать черно-белое фото (не путать с градацией серого, здесь строго два цвета), и сохранил его себе на ноутбук. Когда писал данный пост, вспомнил о нем, и решил тоже прикрепить для общего обозрения. А выглядит он следующим образом:
   header("Content-type: image/jpeg"); 
   $uploadfile = 'image.jpg';
   $source = imagecreatefromjpeg($uploadfile);
   $size = getimagesize($uploadfile);
   $result_source = imagecreatetruecolor($size[0], $size[1]);
   for ($x = 0; $x < $size[0]; $x++) {
    for ($y = 0; $y < $size[1]; $y++) {
     $colors=imagecolorsforindex($source, imagecolorat($source, $x,$y));
     $r=$colors['red'];
     $g=$colors['green'];
     $b=$colors['blue'];
     $random = $r + $g + $b;
     if ($random > (((255 + 20) / 2) * 3)) {
      $r = 255;
      $g = 255;
      $b = 255; }
     else {
      $r = 0;
      $g = 0;
      $b = 0; }
     $color = imagecolorallocate($result_source, $r,$g,$b);
     imagesetpixel($result_source, $x, $y, $color);
    }
   }
   imagejpeg($result_source);
Смотрим, что получилось:

Черно-белое фото

Пикселизация
С версии php 5.3 появилась возможность налаживать фильтр пикселизации, поэтому может не везде быть описание данного фильтра. Я лично, узнал о его существовании только на днях. Тем не менее, из того что я понял, можно сделать такое описание:
imagefilter(image, IMG_FILTER_PIXELATE, block_size, pixelate_effect);
image – наше изображение;
block_size – размер блока в пикселях (что-то типа уровень пикселизации);
pixelate_effect – использовать, или не использовать эффект пикселизации (некое смягчение пикселизации). Принимает значение true, либо false, по умолчанию false.

Для примера попробуем использовать такие значения аргументов:
   header("Content-type: image/jpeg"); 
   $uploadfile = 'image.jpg';
   $source = imagecreatefromjpeg($uploadfile);
   imagefilter($source, IMG_FILTER_PIXELATE, 3, true);
   imagejpeg($source);
Результатом будет картинка:

Эффект пикселизации

Ну вот и все, что хотел написать в данной статье. Надеюсь, для вас нашлось здесь что-нибудь интересное и полезное. ;)

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

Отправить комментарий