function ctools_stylizer_image_processor::command_hue

Colorize the current workspace with the given location.

This uses a color replacement algorithm that retains luminosity but turns replaces all color with the specified color.

File

includes/stylizer.inc, line 480

Class

ctools_stylizer_image_processor

Code

function command_hue($color, $x = NULL, $y = NULL, $width = NULL, $height = NULL) {
    if (!isset($x)) {
        $whole_image = TRUE;
        $x = $y = 0;
        $width = imagesx($this->workspace);
        $height = imagesy($this->workspace);
    }
    $this->log("Hue: {$color} ({$x}, {$y}, {$width}, {$height})");
    list($red, $green, $blue) = _color_unpack($this->palette[$color]);
    // We will create a monochromatic palette based on the input color
    // which will go from black to white.
    // Input color luminosity: this is equivalent to the position of the
    // input color in the monochromatic palette
    $luminosity_input = round(255 * ($red + $green + $blue) / 765);
    // 765 = 255 * 3
    // We fill the palette entry with the input color at itscorresponding position
    $palette[$luminosity_input]['red'] = $red;
    $palette[$luminosity_input]['green'] = $green;
    $palette[$luminosity_input]['blue'] = $blue;
    // Now we complete the palette, first we'll do it to the black, and then to
    // the white.
    // From input to black
    $steps_to_black = $luminosity_input;
    // The step size for each component
    if ($steps_to_black) {
        $step_size_red = $red / $steps_to_black;
        $step_size_green = $green / $steps_to_black;
        $step_size_blue = $blue / $steps_to_black;
        for ($i = $steps_to_black; $i >= 0; $i--) {
            $palette[$steps_to_black - $i]['red'] = $red - round($step_size_red * $i);
            $palette[$steps_to_black - $i]['green'] = $green - round($step_size_green * $i);
            $palette[$steps_to_black - $i]['blue'] = $blue - round($step_size_blue * $i);
        }
    }
    // From input to white
    $steps_to_white = 255 - $luminosity_input;
    if ($steps_to_white) {
        $step_size_red = (255 - $red) / $steps_to_white;
        $step_size_green = (255 - $green) / $steps_to_white;
        $step_size_blue = (255 - $blue) / $steps_to_white;
    }
    else {
        $step_size_red = $step_size_green = $step_size_blue = 0;
    }
    // The step size for each component
    for ($i = $luminosity_input + 1; $i <= 255; $i++) {
        $palette[$i]['red'] = $red + round($step_size_red * ($i - $luminosity_input));
        $palette[$i]['green'] = $green + round($step_size_green * ($i - $luminosity_input));
        $palette[$i]['blue'] = $blue + round($step_size_blue * ($i - $luminosity_input));
    }
    // Go over the specified area of the image and update the colors.
    for ($j = $x; $j < $height; $j++) {
        for ($i = $y; $i < $width; $i++) {
            $color = imagecolorsforindex($this->workspace, imagecolorat($this->workspace, $i, $j));
            $luminosity = round(255 * ($color['red'] + $color['green'] + $color['blue']) / 765);
            $new_color = imagecolorallocatealpha($this->workspace, $palette[$luminosity]['red'], $palette[$luminosity]['green'], $palette[$luminosity]['blue'], $color['alpha']);
            imagesetpixel($this->workspace, $i, $j, $new_color);
        }
    }
}