You are here

function png_color2alpha in ImageCache Actions 6.2

Same name and namespace in other branches
  1. 8 coloractions/transparency.inc \png_color2alpha()
  2. 5.3 transparency.inc \png_color2alpha()
  3. 5.2 transparency.inc \png_color2alpha()
  4. 6 transparency.inc \png_color2alpha()
  5. 7 coloractions/transparency.inc \png_color2alpha()

This achives a tonal effect by converting the images combined tone and existing transparency into one shade value. This is then used as the ALPHA transparency for that pixel, while the whole thing is coloured the same shade. Images 'greytoned' in this manner should sit smoothly on any background.

With no color set, use the existing hue.

To save a partially transparent image, the image resource must be switched to PNG. ... or maybe not. Just flatten it yourself, or switch the format yourself. This hack would produce side effects otherwise.

This algorithm runs maths per-pixel, and therefore is incredibly much more inefficient than any native routine. Will kill the server on large images.

1 call to png_color2alpha()
imagecache_alpha_image in coloractions/transparency.inc
Given an image, manipulate the transparancy behaviour.

File

coloractions/transparency.inc, line 174
Helper functions for the alpha action for imagecache

Code

function png_color2alpha(&$image, $color, $opacity = NULL) {

  #$image->info['extension'] = 'png';

  #$image->info['mime_type'] = 'image/png';
  $info = $image->info;
  if (!$info) {
    return FALSE;
  }
  $im1 = $image->resource;
  imagesavealpha($im1, TRUE);
  imagealphablending($im1, FALSE);
  if ($color) {
    $background = imagecache_actions_hex2rgba($color);
  }
  $width = imagesx($im1);
  $height = imagesy($im1);
  if ($width * $height > 600 * 600) {
    watchdog('imagecache_actions', __FUNCTION__ . " on {$image->source}. Image is TOO BIG to run the per-pixel algorithm. Aborting.");
    return TRUE;
  }
  for ($i = 0; $i < $height; $i++) {

    //this loop traverses each row in the image
    for ($j = 0; $j < $width; $j++) {

      //this loop traverses each pixel of each row

      // Get the color & alpha info of the current pixel.
      $retrieved_color = imagecolorat($im1, $j, $i);

      // an index
      $rgba_array = imagecolorsforindex($im1, $retrieved_color);
      if ($opacity) {

        // It's a user-defined alpha value
        $alpha = (1 - $opacity) * 127;
      }
      else {

        // Calculate the total shade value of this pixel.
        $lightness = ($rgba_array['red'] + $rgba_array['green'] + $rgba_array['blue']) / 3;

        // Need to flip the numbers around before doing maths.

        #$opacity = 1-($rgba_array['alpha']/127);

        #$darkness = 1-($lightness/256); // 0 is white, 1 is black

        #$visibility = $darkness * $opacity;

        #$alpha = (1-$visibility) * 127;
        $alpha = (1 - (1 - $lightness / 256) * (1 - $rgba_array['alpha'] / 127)) * 127;
      }
      if (!$color) {
        $background = $rgba_array;
      }

      // Paint the pixel.
      $color_to_paint = imagecolorallocatealpha($image->resource, $background['red'], $background['green'], $background['blue'], $alpha);
      imagesetpixel($image->resource, $j, $i, $color_to_paint);
    }
  }
  return TRUE;
}