Обработка цветов в скриптах PHP: от основ до продвинутых примеров

Раздел: Разработка на PHP -> Обработка изображений

Основные принципы работы с цветами в PHP

Как получить и изменить цвет отдельного пикселя с помощью GD?

Для низкоуровневой работы с цветами на уровне пикселей в PHP используется расширение GD. Функция imagecolorat() возвращает индекс цвета (для палитровых изображений) или непосредственно значение цвета (для true color). В true color режиме результат можно разложить на составляющие с помощью imagecolorsforindex(). Изменение цвета пикселя выполняется через imagesetpixel() с предварительным созданием нового цвета функцией imagecolorallocate().


// Открываем изображение
$img = imagecreatefromjpeg('photo.jpg');

// Получаем цвет пикселя (50, 50)
$colorIndex = imagecolorat($img, 50, 50);
$rgb = imagecolorsforindex($img, $colorIndex);
echo "R: {$rgb['red']}, G: {$rgb['green']}, B: {$rgb['blue']}";

// Создаём новый цвет (красный)
$red = imagecolorallocate($img, 255, 0, 0);

// Устанавливаем пиксель
imagesetpixel($img, 50, 50, $red);
    

Pictures php id (работа с изображениями в php)

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

Проблема: при обработке больших изображений (более 1 Мп) попиксельный перебор становится крайне медленным. Для True Color изображений GD хранит цвета в формате ARGB, поэтому вызов imagecolorsforindex() для каждого пикселя создаёт накладные расходы. Рекомендуется использовать предварительное получение всего растрового массива через imagecreatetruecolor() и работу с ним.

Типичная ошибка: путаница между палитровыми и true color изображениями. В палитровом режиме imagecolorat() возвращает индекс, а не значение цвета. Используйте imageistruecolor() для проверки.

Как быстро применить готовый фильтр, например преобразование в серый?

В GD встроена функция imagefilter(), которая применяет предопределённые эффекты. Для серого используется константа IMG_FILTER_GRAYSCALE.


$img = imagecreatefromjpeg('photo.jpg');
imagefilter($img, IMG_FILTER_GRAYSCALE);
imagejpeg($img, 'gray.jpg');
imagedestroy($img);
    

Php img alt (вывод атрибута alt изображения в php)

Цель: быстрое получение результата без написания собственной логики. Подходит для стандартных эффектов (яркость, контраст, негатив, размытие).

Проблема: imagefilter() не поддерживает все возможные преобразования (например, изменение оттенка по HSL). Для нестандартных фильтров требуется собственная реализация.

Как работать с цветами через расширение Imagick?

Imagick предоставляет более мощный инструментарий, включая работу с цветовыми пространствами (HSL, CMYK) и продвинутые фильтры. Для изменения оттенка используется метод modulateImage().


$image = new Imagick('photo.jpg');
// Увеличиваем насыщенность на 50%
$image->modulateImage(100, 150, 100);
$image->writeImage('saturated.jpg');
    

Images php (изображения в php)

Цель: профессиональная обработка изображений с гибкими настройками яркости, насыщенности, оттенка. Поддерживает CMYK, ICC-профили.

Проблема: Imagick не входит в стандартную поставку PHP, требует установки. При работе с большими изображениями возможны ошибки памяти – следует увеличить лимит в php.ini или использовать setResourceLimit().

Типичная ошибка: путаница с порядком каналов в modulateImage(): первый параметр – яркость (0-200), второй – насыщенность, третий – оттенок.

Как конвертировать цвета между моделями RGB, HEX, HSL без изображений?

Иногда требуется работать с цветами вне контекста изображения – например, для генерации CSS-стилей. Для конвертации можно написать собственные функции или использовать библиотеки (colorextension, colorjizz).


function hexToRgb($hex) {
    list($r, $g, $b) = sscanf($hex, "#%02x%02x%02x");
    return ['r' => $r, 'g' => $g, 'b' => $b];
}

function rgbToHsl($r, $g, $b) {
    // Стандартный алгоритм
    $r /= 255; $g /= 255; $b /= 255;
    $max = max($r, $g, $b);
    $min = min($r, $g, $b);
    $l = ($max + $min) / 2;
    if ($max == $min) {
        $h = $s = 0;
    } else {
        $d = $max - $min;
        $s = $l > 0.5 ? $d / (2 - $max - $min) : $d / ($max + $min);
        switch ($max) {
            case $r: $h = ($g - $b) / $d + ($g < $b ? 6 : 0); break;
            case $g: $h = ($b - $r) / $d + 2; break;
            case $b: $h = ($r - $g) / $d + 4; break;
        }
        $h /= 6;
    }
    return ['h' => $h * 360, 's' => $s * 100, 'l' => $l * 100];
}
    

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

Проблема: точность преобразований – при конвертации HSL в RGB возможна потеря цвета из-за округлений. Рекомендуется использовать библиотеки с проверенным кодом.

Расширенные примеры цветовых операций

Пример 1. Создание градиента между двумя цветами

Градиент строится путём линейной интерполяции RGB-компонент от начального цвета к конечному. Результат – изображение-градиент.

Пример

// Начальный и конечный цвета (RGB)
$color1 = [255, 0, 0]; // красный
$color2 = [0, 0, 255]; // синий
$width = 256;
$height = 100;

$img = imagecreatetruecolor($width, $height);
for ($x = 0; $x < $width; $x++) {
    $ratio = $x / ($width - 1);
    $r = (int)($color1[0] + ($color2[0] - $color1[0]) * $ratio);
    $g = (int)($color1[1] + ($color2[1] - $color1[1]) * $ratio);
    $b = (int)($color1[2] + ($color2[2] - $color1[2]) * $ratio);
    $color = imagecolorallocate($img, $r, $g, $b);
    imageline($img, $x, 0, $x, $height-1, $color);
}
imagepng($img, 'gradient.png');
imagedestroy($img);
Результат: файл gradient.png с плавным переходом от красного к синему слева направо.

Пример 2. Изменение оттенка всего изображения (hue shift) с помощью Imagick

Сдвиг оттенка (hue) на заданное количество градусов выполняется через цветовое пространство HSL. Imagick позволяет манипулировать каналами отдельно.

Пример

$image = new Imagick('photo.jpg');
// Преобразуем в HSL
$image->transformImageColorspace(Imagick::COLORSPACE_HSL);

// Получаем пиксельный итератор
$pixels = $image->getPixelRegionIterator(0, 0, $image->getImageWidth(), $image->getImageHeight());
foreach ($pixels as $pixel) {
    $hsl = $pixel->getHSL();
    // Сдвигаем оттенок на 60 градусов
    $hsl['hue'] = fmod($hsl['hue'] + 60/360, 1);
    $pixel->setHSL($hsl['hue'], $hsl['saturation'], $hsl['luminosity']);
    $pixels->syncIterator();
}

// Возвращаем в RGB
$image->transformImageColorspace(Imagick::COLORSPACE_SRGB);
$image->writeImage('hue_shifted.jpg');
Результат: изображение с изменённым оттенком (все цвета сдвинуты на 60 градусов).

Пример 3. Построение гистограммы RGB с помощью GD

Гистограмма показывает распределение яркости каждого канала. Полезна для анализа экспозиции и цветового баланса.

Пример

$img = imagecreatefromjpeg('photo.jpg');
$width = imagesx($img);
$height = imagesy($img);

$hist = ['r' => array_fill(0, 256, 0), 'g' => array_fill(0, 256, 0), 'b' => array_fill(0, 256, 0)];

for ($y = 0; $y < $height; $y++) {
    for ($x = 0; $x < $width; $x++) {
        $rgb = imagecolorat($img, $x, $y);
        $r = ($rgb >> 16) & 0xFF;
        $g = ($rgb >> 8) & 0xFF;
        $b = $rgb & 0xFF;
        $hist['r'][$r]++;
        $hist['g'][$g]++;
        $hist['b'][$b]++;
    }
}

// Вывод для проверки (первые 10 значений красного канала)
print_r(array_slice($hist['r'], 0, 10, true));
Array
(
    [0] => 125
    [1] => 98
    [2] => 102
    ...
)

Пример 4. Инвертирование изображения без использования imagefilter

Инвертирование – замена каждого канала на его дополнение до 255. Такой подход даёт полный контроль над обработкой.

Пример

$img = imagecreatefromjpeg('input.jpg');
$width = imagesx($img);
$height = imagesy($img);
$newImg = imagecreatetruecolor($width, $height);

for ($y = 0; $y < $height; $y++) {
    for ($x = 0; $x < $width; $x++) {
        $rgb = imagecolorat($img, $x, $y);
        $r = 255 - (($rgb >> 16) & 0xFF);
        $g = 255 - (($rgb >> 8) & 0xFF);
        $b = 255 - ($rgb & 0xFF);
        $newColor = imagecolorallocate($newImg, $r, $g, $b);
        imagesetpixel($newImg, $x, $y, $newColor);
    }
}
imagejpeg($newImg, 'inverted.jpg');
imagedestroy($img);
imagedestroy($newImg);
Результат: изображение с инвертированными цветами (негатив).

работа с цветами в PHP - comments

En
Color php (php)