- 29-01-2008
Играем с изображением в PHP
Оригинал на http://www.phpied.com/image-fun/
Перевод Феськов Кузьма (kuzma@russofile.ru, http://php.russofile.ru)
В данном материале мы рассмотрим некоторые примеры манипуляции с изображением при помощи библиотеки GD, а именно – операции с пикселями. Манипуляции с пикселом означают, что действие будет относиться только к нему не затрагивая все окружающие пиксели.
Например, мы можем сделать негатив изображения. Для этого берем каждый пиксель в изображении и заменяем его противоположным цветом.
Хорошо, но как это работает? Очень просто. Я беру картинку PNG, прохожу по каждому пикселю этого изображения и передаю его функции, которая принимает пиксель в качестве параметра. Функция возвращает мне новый пиксель. Я складываю все новые пиксели и получаю новое изображение.
Класс для работы с пикселом
Для начала нам понадобится класс для работы с пикселом. Он очень прост – содержит в себе три значения: красного, зеленого и синего.
<?php |
Этот класс имеет только одну функцию – конструктор, которая сохраняет RGB значения пикселя.
Чтобы создать красный пиксел, вы просто делаете:
<?php |
Класс манипуляций с пикселами: главный метод
Далее мы создаем класс, который проделывает фактические действия с изображением. Назовем его Image_PixelOperations(). Я не стал писать удобного интерфейса для обработки различных форматов картинок, я думаю, что вы можете развить его самостоятельно. Все, что мне было нужно – это более простой метод для открытия PNG файлов, который бы проходил по каждому пикселу файла, вызывает функцию, получает новый пиксел и присваивает его новому изображению. Далее приведу текст метода:
<?php |
Метод принимает путь до файла. Никаких проверок не производит, предполагая, что это правильный PNG файл. Второй параметр – это имя нового файла изображения. Третий – функция, которая будет вызываться для каждого пикселя. И последний параметр – это любой дополнительный параметр, который мы хотели бы передать в вызываемую для пиксела функцию.
Добавляем шумов
И так, пришло время, чтобы написать первую функцию обработки пиксела: addNoise(). Добавление шума к изображению означает добавление случайного значения к каждому каналу пикселя (если у вас возник вопрос, что такое канал, то я отвечу – уровень красного цвета в пикселе = канал, тоже самое с зеленым и синим). Далее привожу функцию:
<?php |
Что представляет из себя функция? Она получает случайное число в указанном пользователем диапазоне ($factor). И добавляет его к значению каналов пиксела. Пользователь указывает диапазон уровня шума: 0 – нет шума, 255 – очень много шума.
Давайте проверять! Создаем простую HTML форму:
<form method="get"> |
Она принимает параметр – названия файла с изображением. После получения этого параметра я создаю новый объект класса для работы с пикселами:
<?php |
Далее я показываю оригинальное изображение, а затем результат обработки.
<?php |
Результат:

Вот еще примеры. Первое изображение получено при помощи фактора 20, а второе – 500:

Управление яркостью
Давайте теперь попробуем поиграть с яркостью изображения. Нижеприведенная функция добавляет целое число (одно и тоже) к каждому каналу пиксела. Если мы вызываем функцию с положительным значением – яркость увеличивается, если с отрицательным – уменьшается.
<?php |
Чтобы протестировать эту функцию выполните следующий код:
<?php |
Смотрим на результат:

Меняем местами цвета
Давайте теперь займемся сменой цветов. Это означает, что мы можем взять, скажем, количество красных цветов и заменить их, например, на количество синих цветов. Возможные варианты:
- RGB to RBG
- RGB to BGR
- RGB to BRG
- RGB to GBR
- RGB to GRB
Давайте посмотрим, как выглядит функция:
<?php |
Тестируем:
RGB -> RBG![]() | RGB -> BGR![]() | RGB -> BRG![]() |
RGB -> GBR![]() | RGB -> GRB![]() |
Удаление или насыщение цветов
Далее рассматриваем еще 2 функции. Первая – устанавливает значение цвета в 0 (например, нет красного). Вторая – наоборот увеличивает колличество цвета до максимального значения, или сразу 2 канала. Таким образом, мы имеем 6 вариантов значений для каждого метода.
- Удаление (или насыщение) красный
- Удаление (или насыщение) зеленый
- Удаление (или насыщение) синий
- Удаление (или насыщение) красный и зеленый в то же самое время
- Удаление (или насыщение) красный и синий
- Удаление (или насыщение) зеленый и синий
Код:
<?php |
Результаты:
Удаляем красный![]() | Удаляем зеленый![]() | Удаляем синий![]() |
Удаляем красный и зеленый![]() | Удаляем зеленый и синий![]() | Удаляем красный и синий![]() |
Насыщаем красный![]() | Насыщаем зеленый![]() | Насыщаем синий![]() |
Насыщаем красный и зеленый![]() | Насыщаем зеленый и синий![]() | Насыщаем красный и синий![]() |
Делаем негатив
Эта функция очень проста – у вас много красного? Значит сделаем мало. И так далее.
<?php |
Результат:

Оттенки серого (Grayscale)
Не знаю, в курсе вы или нет, но оттенок серого получается уравниванием R, G, B каналов. Более темные участки имеют больше насыщения, светлые – меньше.
Чтобы привести изображение к оттенкам серого мы должны взять среднее число насыщения каналов и установить их на среднее число.
<?php |
Результат:

Черно-белое
В отличие от оттенков серого, черно-белое изображение имеет только 2 цвета: черный (0,0,0) и белый (255,255,255). $factor мы будем использовать для определения границы того, что считать черным, а что – белым. Простота логики в том, что мы суммируем R+G+B и смотрим, к чему значение ближе – к 255 или к 0. Использование $factor позволит нам внести некоторую гибкость в алгоритм (внести некоторую субъективность):
<?php |
Результат ($factor = 20):

Отсечение
Не знаю, насколько эта функция может оказаться полезной. Она занимается удалением пограничных значений (переходов) цвета, заменя их чистым цветом: если у вас было 5, 155, 250 станет – 0, 155, 255. $factor дает нам гибкость в рисунке. Пока я вижу нужность этой функции для уменьшения размера изображения.
<?php |
Результат ($factor = 100):

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
















