You are here

function image_imagemagick_image_effects_text in ImageCache Actions 7

Same name and namespace in other branches
  1. 8 image_effects_text/image_effects_text.inc \image_imagemagick_image_effects_text()

Imagemagick toolkit specific implementation of the text effect.

Text in Imagemagick:

UTF-8/non-ascii characters: To prevent problems with non-ASCII characters, the online manual suggests to put the text in a file and use the file} syntax. This does not work with the text primitive of the -draw command, so we use -annotate. We put the text in a temporary file which will be deleted by our hook_exit(). http://www.imagemagick.org/Usage/windows/#character_encoding

Alignment in Imagemagick: This is not directly supported, though a justification option has been proposed: http://www.imagemagick.org/Usage/bugs/future/#justification.

What we do have is the gravity option: Gravity is used to position a text, but it also automatically applies a justification based on that placement. So we use gravity here for alignment, but will thus have to rebase our positioning.

Gravity |halign|valign |hpos change|vpos change ------------------------------------------------ NorthWest left top 0 0 North center top -width/2 0 NorthEast right top -width 0 West left center 0 -height/2 Center center center -width/2 -height/2 East right center -width -height/2 SouthWest left bottom 0 -height South center bottom -width/2 -height SouthEast right bottom -width -height

Parameters

stdClass $image:

array $data: The parameters for this effect.

Return value

bool true on success, false otherwise.

File

image_effects_text/image_effects_text.inc, line 466

Code

function image_imagemagick_image_effects_text(stdClass $image, array $data) {
  static $alignments2gravity = array(
    'left' => array(
      'top' => array(
        'gravity' => 'NorthWest',
        'tx' => 0,
        'ty' => 0,
      ),
      'center' => array(
        'gravity' => 'West',
        'tx' => 0,
        'ty' => -0.5,
      ),
      'bottom' => array(
        'gravity' => 'SouthWest',
        'tx' => 0,
        'ty' => 1,
      ),
    ),
    'center' => array(
      'top' => array(
        'gravity' => 'North',
        'tx' => -0.5,
        'ty' => 0,
      ),
      'center' => array(
        'gravity' => 'Center',
        'tx' => -0.5,
        'ty' => -0.5,
      ),
      'bottom' => array(
        'gravity' => 'South',
        'tx' => -0.5,
        'ty' => 1,
      ),
    ),
    'right' => array(
      'top' => array(
        'gravity' => 'NorthEast',
        'tx' => 1,
        // reversed translation
        'ty' => 0,
      ),
      'center' => array(
        'gravity' => 'East',
        'tx' => 1,
        // reversed translation
        'ty' => -0.5,
      ),
      'bottom' => array(
        'gravity' => 'SouthEast',
        'tx' => 1,
        // reversed translation
        'ty' => 1,
      ),
    ),
  );

  // Convert color and alpha to Imagemagick rgba color argument.
  $alpha = $data['alpha'] / 100;
  $color = 'rgba(' . $data['RGB']['red'] . ',' . $data['RGB']['green'] . ',' . $data['RGB']['blue'] . ',' . $alpha . ')';

  // Set gravity for the alignment and calculate the translation to the
  // requested x and y offset as starting from the gravity point.
  $alignment_corrections = $alignments2gravity[$data['halign']][$data['valign']];
  $gravity = $alignment_corrections['gravity'];
  if ($alignment_corrections['tx'] > 0) {
    $data['xpos'] = (int) ($alignment_corrections['tx'] * $image->info['width'] - $data['xpos']);
  }
  else {
    $data['xpos'] += (int) ($alignment_corrections['tx'] * $image->info['width']);
  }
  if ($alignment_corrections['ty'] > 0) {
    $data['ypos'] = (int) ($alignment_corrections['ty'] * $image->info['height'] - $data['ypos']);
  }
  else {
    $data['ypos'] += (int) ($alignment_corrections['ty'] * $image->info['height']);
  }

  // Add signs to translation, also when positive or 0.
  if ($data['xpos'] >= 0) {
    $data['xpos'] = '+' . $data['xpos'];
  }
  if ($data['ypos'] >= 0) {
    $data['ypos'] = '+' . $data['ypos'];
  }

  // Angle must be positive.
  if ($data['angle'] < 0) {
    $data['angle'] = $data['angle'] % 360 + 360;
  }

  // Set font file, size and color. fontpath is the real path, not a wrapper.
  $image->ops[] = '-font ' . escapeshellarg($data['fontpath']);
  $image->ops[] = "-pointsize {$data['size']}";
  $image->ops[] = '-fill ' . escapeshellarg($color);

  // Add text to a temporary file,
  $tmp_file_name = drupal_tempnam('temporary://', 'image_effects_text');
  $tmp_file = fopen($tmp_file_name, 'w');
  if ($tmp_file) {
    fwrite($tmp_file, $data['text']);
    fclose($tmp_file);

    // and inform our hook_exit about it.
    image_effects_text_exit($tmp_file_name);
    $tmp_file_name = drupal_realpath($tmp_file_name);
    $text = "@{$tmp_file_name}";
  }
  else {

    // Fallback to pass the text via the command line, let's hope there are no
    // non-ASCII characters or that it works anyway (OS and locale dependent).
    $text = $data['text'];
  }

  // Add gravity.
  $image->ops[] = "-gravity {$gravity}";

  // Add text angle, position and text (file) itself.
  $image->ops[] = "-annotate {$data['angle']}x{$data['angle']}{$data['xpos']}{$data['ypos']} " . escapeshellarg($text);
  return TRUE;
}