You are here

function ctools_stylizer_image_processor::command_hue in Chaos Tool Suite (ctools) 7

Same name and namespace in other branches
  1. 6 includes/stylizer.inc \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
Create customized CSS and images from palettes created by user input.

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);
    }
  }
}