You are here

function imageapi_gd_image_roundedcorners in ImageCache Actions 6

Same name and namespace in other branches
  1. 6.2 canvasactions/rounded_corners.inc \imageapi_gd_image_roundedcorners()

Trim rounded corners off an image, using an anti-aliasing algorithm.

Implementation of hook_image()

Note, this is not image toolkit-agnostic yet! It just assumes GD. We can abstract it out once we have something else to abstract to. In the meantime just don't.

'handcoded' rounded corners logic contributed by donquixote 2009-08-31

Parameters

$image:

$action:

File

./canvasactions.inc, line 724
Helper functions for the text2canvas action for imagecache

Code

function imageapi_gd_image_roundedcorners(&$image, $action = array()) {

  // Read settings.
  $width = $image->info['width'];
  $height = $image->info['height'];
  $radius = $action['radius'];
  $independent_corners = !empty($action['independent_corners_set']['independent_corners']);
  $corners = array(
    'tl',
    'tr',
    'bl',
    'br',
  );
  $im =& $image->resource;

  // Prepare drawing on the alpha channel.
  imagesavealpha($im, TRUE);
  imagealphablending($im, FALSE);
  foreach ($corners as $key) {
    if ($independent_corners) {
      $r = $action['independent_corners_set']['radii'][$key];
    }
    else {

      // Use the all-the-same radius setting.
      $r = $radius;
    }

    // key can be 'tl', 'tr', 'bl', 'br'.
    $is_bottom = $key[0] == 'b';
    $is_right = $key[1] == 'r';

    // dx and dy are in "continuous coordinates",
    // and mark the distance of the pixel middle to the image border.
    for ($dx = 0.5; $dx < $r; ++$dx) {
      for ($dy = 0.5; $dy < $r; ++$dy) {

        // ix and iy are in discrete pixel indices,
        // counting from the top left
        $ix = floor($is_right ? $width - $dx : $dx);
        $iy = floor($is_bottom ? $height - $dy : $dy);
        $opacity = _canvasactions_roundedcorners_pixel_opacity($dx, $dy, $r);
        if ($opacity >= 1) {

          // we can finish this row,
          // all following pixels will be fully opaque.
          break;
        }

        // Color lookup at ($ix, $iy).
        $color_ix = imagecolorat($im, $ix, $iy);
        $color = imagecolorsforindex($im, $color_ix);
        if (isset($rgba['alpha'])) {
          $color['alpha'] = 127 - round($opacity * (127 - $color['alpha']));
        }
        else {
          $color['alpha'] = 127 - round($opacity * 127);
        }

        // Value should not be more than 127, and not less than 0.
        $color['alpha'] = $color['alpha'] > 127 ? 127 : ($color['alpha'] < 0 ? 0 : $color['alpha']);
        $color_ix = imagecolorallocatealpha($im, $color['red'], $color['green'], $color['blue'], $color['alpha']);
        imagesetpixel($im, $ix, $iy, $color_ix);
      }
    }
  }
  return TRUE;
}