You are here

imagecache_coloractions.module in ImageCache Actions 6.2

Additional actions for imagecache processing.

Exposes some of the simpler PHP 'imagefilter' actions (colorshift, brightness, negative) and provides some more expensive color manipulation tools akin to Photoshop or Gimp (Overlay)

  • A transparency masker for merging with backgrounds.
  • A pseudo - file conversion feature.

@author dan http://coders.co.nz @author sydneyshan http://enigmadigital.net.au

File

coloractions/imagecache_coloractions.module
View source
<?php

/**
 * @file
 * Additional actions for imagecache processing.
 *
 * Exposes some of the simpler PHP 'imagefilter' actions (colorshift,
 * brightness, negative) and provides some more expensive color manipulation
 * tools akin to Photoshop or Gimp (Overlay)
 * -  A transparency masker for merging with backgrounds.
 * -  A pseudo - file conversion feature.
 *
 *
 * @author dan http://coders.co.nz
 * @author sydneyshan http://enigmadigital.net.au
 */

// During devel, caching is pointless. Flush it

//imagecache_action_definitions(TRUE);
if (!function_exists('imagecache_actions_calculate_relative_position')) {
  module_load_include('inc', 'imagecache_actions', 'utility');
}
module_load_include('inc', 'imagecache_actions', 'utility-color');

/**
 * Implementation of hook_imagecache_actions().
 *
 * Declare available actions, return help text about this filter.
 */
function imagecache_coloractions_imagecache_actions() {
  $actions = array(
    'imagecache_colorshift' => array(
      'name' => 'Color Shift',
      'description' => 'Adjust image colors.',
    ),
    'imagecache_coloroverlay' => array(
      'name' => 'Color Overlay',
      'description' => 'Apply a color tint to an image (retaining blacks and whites).',
    ),
    'imagecache_brightness' => array(
      'name' => 'Brightness',
      'description' => 'Adjust image brightness.',
    ),
    'imagecache_inverse' => array(
      'name' => t('Negative Image'),
      'description' => t('Invert colors and brightness.'),
    ),
    'imagecache_convert' => array(
      'name' => t('Change File format'),
      'description' => t('Choose to save the image as a different filetype.'),
    ),
    'imagecache_alpha' => array(
      'name' => t('Alpha Transparency'),
      'description' => t('Adjust transparency.'),
      'file' => 'transparency.inc',
    ),
  );
  return $actions;
}

/**
 * Display the settings for this action
 */
function imagecache_coloractions_theme() {
  return array(
    'imagecache_colorshift' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'imagecache_coloroverlay' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'imagecache_alpha' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'imagecache_brightness' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'imagecache_convert' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
  );
}

/**
 * Implementation of imagecache_hook_form()
 *
 * Settings for colorshift actions.
 *
 * @param $action array of settings for this action
 * @return a form definition
 */
function imagecache_colorshift_form($action) {
  $defaults = array(
    'RGB' => array(
      'HEX' => '#FF0000',
    ),
  );
  $action = array_merge($defaults, (array) $action);
  $form = array(
    '#theme' => 'imagecache_rgb_form',
  );
  $form['RGB'] = imagecache_rgb_form($action['RGB']);
  $form['note'] = array(
    '#value' => t("<p>\n    Note that colorshift is a mathematical filter that doesn't always\n    have the expected result.\n    To shift an image precisely TO a target color,\n    desaturate (greyscale) it before colorizing.\n    The hue (color wheel) is the <em>direction</em> the\n    existing colors are shifted. The tone (inner box) is the amount.\n    Keep the tone half-way up the left site of the color box\n    for best results.\n  </p>"),
  );
  return $form;
}

/**
 * Implementation of theme_hook() for imagecache_ui.module
 */
function theme_imagecache_colorshift($element) {
  $action = $element['#value'];
  return theme_imagecacheactions_rgb($action['RGB']);
}

/**
 * Implementation of hook_image()
 *
 * Process the imagecache action on the passed image
 *
 * Just converts and passes the vals to the all-purpose 'filter' action
 */
function imagecache_colorshift_image(&$image, $data = array()) {

  // convert color from hex (as it is stored in the UI)
  if ($data['RGB']['HEX'] && ($deduced = hex_to_rgb($data['RGB']['HEX']))) {
    $data['RGB'] = array_merge($data['RGB'], $deduced);
  }
  return imageapi_toolkit_invoke('colorshift', $image, array(
    $data,
  ));
}

/**
 * Implementation of hook_{toolkit}_image()
 */
function imageapi_gd_image_colorshift(&$image, $data = array()) {
  $RGB = $data['RGB'];
  if (!function_exists('imagefilter')) {
    require_once drupal_get_path('module', 'imageapi_gd') . '/imagefilter.inc';
  }
  return imagefilter($image->resource, 4, $RGB['red'], $RGB['green'], $RGB['blue']);
}
function imageapi_imagemagick_image_colorshift(&$image, $data = array()) {
  $RGB = $data['RGB'];
  $image->ops[] = "-fill rgb\\({$RGB['red']},{$RGB['green']},{$RGB['blue']}\\) -colorize 50\\%";
  return TRUE;
}

/**
 * Implementation of imagecache_hook_form()
 *
 * Settings for coloroverlay actions.
 *
 * @param $action array of settings for this action
 * @return a form definition
 */
function imagecache_coloroverlay_form($action) {
  $defaults = array(
    'RGB' => array(
      'HEX' => '#E2DB6A',
    ),
  );
  $action = array_merge($defaults, (array) $action);
  $form = array(
    '#theme' => 'imagecache_rgb_form',
  );
  $form['RGB'] = imagecache_rgb_form($action['RGB']);
  $form['note'] = array(
    '#value' => t("<p>\n    Note that color overlay is a mathematical filter that doesn't always\n    have the expected result.\n    To shift an image precisely TO a target color,\n    desaturate (greyscale) it before colorizing.\n    The hue (color wheel) is the <em>direction</em> the\n    existing colors are shifted. The tone (inner box) is the amount.\n    Keep the tone half-way up the left site of the color box\n    for best results.\n  </p>"),
  );
  return $form;
}

/**
 * Implementation of theme_hook() for imagecache_ui.module
 */
function theme_imagecache_coloroverlay($element) {
  $action = $element['#value'];
  return theme_imagecacheactions_rgb($action['RGB']);
}

/**
 * Implementation of hook_image()
 *
 * Process the imagecache action on the passed image
 *
 * Just converts and passes the vals to the all-purpose 'filter' action
 */
function imagecache_coloroverlay_image(&$image, $data = array()) {

  // convert color from hex (as it is stored in the UI)
  if ($data['RGB']['HEX'] && ($deduced = hex_to_rgb($data['RGB']['HEX']))) {
    $data['RGB'] = array_merge($data['RGB'], $deduced);
  }
  return imageapi_toolkit_invoke('coloroverlay', $image, array(
    $data,
  ));
}

/**
 * Implementation of hook_{toolkit}_image()
 */
function imageapi_gd_image_coloroverlay(&$image, $data = array()) {
  $RGB = $data['RGB'];
  $w = $image->info['width'];
  $h = $image->info['height'];
  for ($y = 0; $y < $h; $y++) {
    for ($x = 0; $x < $w; $x++) {
      $rgb = imagecolorat($image->resource, $x, $y);
      $source = imagecolorsforindex($image->resource, $rgb);
      if ($source['red'] <= 128) {
        $final_r = 2 * $source['red'] * $RGB['red'] / 256;
      }
      else {
        $final_r = 255 - (255 - 2 * ($source['red'] - 128)) * (255 - $RGB['red']) / 256;
      }
      if ($source['green'] <= 128) {
        $final_g = 2 * $source['green'] * $RGB['green'] / 256;
      }
      else {
        $final_g = 255 - (255 - 2 * ($source['green'] - 128)) * (255 - $RGB['green']) / 256;
      }
      if ($source['blue'] <= 128) {
        $final_b = 2 * $source['blue'] * $RGB['blue'] / 256;
      }
      else {
        $final_b = 255 - (255 - 2 * ($source['blue'] - 128)) * (255 - $RGB['blue']) / 256;
      }
      $final_colour = imagecolorallocatealpha($image->resource, $final_r, $final_g, $final_b, $source['alpha']);
      imagesetpixel($image->resource, $x, $y, $final_colour);
    }
  }
  return TRUE;
}
function imageapi_imagemagick_image_coloroverlay(&$image, $data = array()) {
  $RGB = $data['RGB'];
  $image->ops[] = "\\( +clone +matte -fill rgb\\({$RGB['red']},{$RGB['green']},{$RGB['blue']}\\) -colorize 100% +clone +swap -compose overlay -composite \\) -compose SrcIn -composite";
  return TRUE;
}

/**
 * Implementation of imagecache_hook_form()
 *
 * Settings for colorshift actions.
 *
 * @param $action array of settings for this action
 * @return a form definition
 */
function imagecache_brightness_form($action) {
  $default = array(
    'filter_arg1' => '100',
  );
  $action = array_merge($default, (array) $action);
  $form = array();
  $form['help'] = array(
    '#value' => t("The brightness effect seldom looks good on its own, but can be useful to wash out an image before making it transparent - eg for a watermark."),
  );
  $form['filter_arg1'] = array(
    '#type' => 'textfield',
    '#title' => t('Brightness'),
    '#description' => t('-255 - +255'),
    '#default_value' => $action['filter_arg1'],
    '#size' => 3,
  );
  return $form;
}

/**
 * Implementation of hook_image()
 *
 * Process the imagecache action on the passed image
 */
function imagecache_brightness_image(&$image, $data = array()) {
  return imageapi_toolkit_invoke('brightness', $image, array(
    $data,
  ));
}

/**
 * image toolkit callbacks
 */
function imageapi_gd_image_brightness(&$image, $data = array()) {
  if (!function_exists('imagefilter')) {
    require_once drupal_get_path('module', 'imageapi_gd') . '/imagefilter.inc';
  }
  return imagefilter($image->resource, 2, $data['filter_arg1']);
}
function imageapi_imagemagick_image_brightness(&$image, $data = array()) {
  $image->ops[] = "-modulate " . (int) (100 + $data['filter_arg1'] / 128 * 100);
  return TRUE;
}

/**
 * Implementation of theme_hook() for imagecache_ui.module
 */
function theme_imagecache_brightness($element) {
  return t("Adjust") . " : " . $element['#value']['filter_arg1'];
}

/**
 * Implementation of imagecache_hook_form()
 *
 * No settings.
 *
 * @param $action array of settings for this action
 * @return a form definition
 */
function imagecache_inverse_form($action) {
  $form = array();
  return $form;
}

/**
 * Implementation of hook_image()
 *
 * Process the imagecache action on the passed image
 */
function imagecache_inverse_image(&$image, $data = array()) {
  return imageapi_toolkit_invoke('inverse', $image, array(
    $data,
  ));
}

/**
 * image toolkit callbacks
 */
function imageapi_gd_image_inverse(&$image, $data = array()) {
  if (!function_exists('imagefilter')) {
    require_once drupal_get_path('module', 'imageapi_gd') . '/imagefilter.inc';
  }
  return imagefilter($image->resource, 0);
}
function imageapi_imagemagick_image_inverse(&$image, $data = array()) {

  // TODO
  return FALSE;
}

/**
 * Implementation of imagecache_hook_form()
 *
 * @param $action array of settings for this action
 * @return a form definition
 */
function imagecache_convert_form($action) {
  if (image_get_toolkit() === 'imageapi_imagemagick') {
    drupal_set_message('When using imagemagick, convert format must be the last effect. If not, results will be unpredictable.', 'warning');
  }
  $form = array(
    'help' => array(
      '#type' => 'markup',
      '#value' => t("If you've been using transparencies in the process, the result may get saved as a PNG (as the image was treated as a one in in-between processes). If this is not desired (file sizes may get too big) you should use this process to force a flatten action before saving. "),
    ),
    'help2' => array(
      '#type' => 'markup',
      '#value' => t("For technical reasons, changing the file format within imagecache does <em>not</em> change the filename suffix. A png may be saved as a *.jpg or vice versa. This may confuse some browsers and image software, but most of them have no trouble. "),
    ),
    'format' => array(
      '#title' => t("File format"),
      '#type' => 'select',
      '#default_value' => isset($action['format']) ? $action['format'] : 'image/png',
      '#options' => imagecache_file_formats(),
    ),
    'quality' => array(
      '#type' => 'textfield',
      '#title' => t('JPEG quality'),
      '#description' => t('Define the image quality for JPEG manipulations only. Ranges from 0 to 100. Higher values mean better image quality, but bigger files.<br /><strong>Has no effect if jpg is not selected.</strong>'),
      '#size' => 10,
      '#maxlength' => 3,
      '#default_value' => isset($action['quality']) ? $action['quality'] : '75',
      '#field_suffix' => '%',
    ),
  );
  return $form;
}

/**
 * Implementation of theme_hook() for imagecache_ui.module
 */
function theme_imagecache_convert($element) {
  $data = $element['#value'];
  $formats = imagecache_file_formats();
  if ($formats[$data['format']] == 'jpg') {
    return t('Convert to: @format, quality: @quality%', array(
      '@format' => $formats[$data['format']],
      '@quality' => $data['quality'],
    ));
  }
  else {
    return t("Convert to") . ": " . $formats[$data['format']];
  }
}

/**
 * Implementation of hook_image()
 *
 * Process the imagecache action on the passed image
 */
function imagecache_convert_image(&$image, $data = array()) {
  $formats = imagecache_file_formats();
  $image->info['mime_type'] = $data['format'];
  $image->info['extension'] = $formats[$data['format']];
  $image->quality = $data['quality'];
  return TRUE;
}
function imagecache_file_formats() {
  return array(
    'image/jpeg' => 'jpg',
    'image/gif' => 'gif',
    'image/png' => 'png',
  );
}

Functions

Namesort descending Description
imageapi_gd_image_brightness image toolkit callbacks
imageapi_gd_image_coloroverlay Implementation of hook_{toolkit}_image()
imageapi_gd_image_colorshift Implementation of hook_{toolkit}_image()
imageapi_gd_image_inverse image toolkit callbacks
imageapi_imagemagick_image_brightness
imageapi_imagemagick_image_coloroverlay
imageapi_imagemagick_image_colorshift
imageapi_imagemagick_image_inverse
imagecache_brightness_form Implementation of imagecache_hook_form()
imagecache_brightness_image Implementation of hook_image()
imagecache_coloractions_imagecache_actions Implementation of hook_imagecache_actions().
imagecache_coloractions_theme Display the settings for this action
imagecache_coloroverlay_form Implementation of imagecache_hook_form()
imagecache_coloroverlay_image Implementation of hook_image()
imagecache_colorshift_form Implementation of imagecache_hook_form()
imagecache_colorshift_image Implementation of hook_image()
imagecache_convert_form Implementation of imagecache_hook_form()
imagecache_convert_image Implementation of hook_image()
imagecache_file_formats
imagecache_inverse_form Implementation of imagecache_hook_form()
imagecache_inverse_image Implementation of hook_image()
theme_imagecache_brightness Implementation of theme_hook() for imagecache_ui.module
theme_imagecache_coloroverlay Implementation of theme_hook() for imagecache_ui.module
theme_imagecache_colorshift Implementation of theme_hook() for imagecache_ui.module
theme_imagecache_convert Implementation of theme_hook() for imagecache_ui.module