Page 1 of 1

Text functions

Posted: 2009-06-24T18:20:21-07:00
by robcolburn
Feel free to revise, took me a while to dig through docs/articles


Some Functions for the community,

Code: Select all

/**
  * applyImage
  * @param imCanvas - Imagick object to apply image to
  * @param src - the path/url to the relavent image file
  * @param x - optional, x-coord to start applying image
  * @param y - optional, y-coord to start applying image
  * @param w - optional, pre-crop image to this width
  * @param h - optional, pre-crop image to this height
  **/
function applyImage($imCanvas, $src = '', $x = 0, $y = 0, $w = 0, $h = 0) {
	$img = new Imagick();
	$img->readImageFile(fopen($src, 'rb'));
	if (!empty($w) && !empty($h)) $img->cropThumbnailImage($w, $h);
	$imCanvas->compositeImage($img, Imagick::COMPOSITE_DEFAULT, $x, $y);
	$img->destroy();
}
/*.................................................................*/

/**
  * applyText
  * @param imCanvas - Imagick object to apply image to
  * @param text - text to apply
  * @param font - font file to use
  * @param x - optional, x-coord to start applying text
  * @param y - optional, y-coord to start applying text
  * @param w - optional, max width of text box
  * @param h - optional, max height of text box
  **/
function applyText($imCanvas, $text = '', $font = 'Arial', $fontSize = 10, $color = '#000000', $x = 0, $y = 0, $w = 0, $h = 0) {
	$w = $w ? $w : ($imCanvas->getImageWidth() - $x);
	$h = $h ? $h : ($imCanvas->getImageHeight() - $y);
	
	$temp = new Imagick();
	$temp->newImage($w, $h, 'transparent');
	$textSettings = new ImagickDraw();
	$textSettings->setFont($font);
	$textSettings->setFontSize($fontSize);
	$textSettings->setFillColor(new ImagickPixel($color));
	$textSettings->setGravity(Imagick::GRAVITY_NORTHWEST);
	annotateWrapped($temp, $textSettings, $text);
	
	$imCanvas->compositeImage($temp, Imagick::COMPOSITE_OVER, $x, $y);
	$textSettings->destroy();
	$temp->destroy();
}
/*.................................................................*/

/**
  * applyText
  * @param imCanvas - Imagick object to apply image to
  * @param imdSettings - ImagickDraw object that holds font settings
  * @param text - text to apply
  * 
  * @thanks http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
  **/
function annotateWrapped($imCanvas, $imdSettings, $text = '') {
	$maxWidth = $imCanvas->getImageWidth();
	$metrics = $imCanvas->queryFontMetrics($imdSettings, $text);
	if ($metrics["textWidth"] > $maxWidth) {
		$avgCharWidth = $metrics["textWidth"] / strlen($text);
		$charsPerLine = floor($maxWidth / $avgCharWidth);
		$text = preg_replace('/(.{1,'.$charsPerLine.'})( +|$\n?)|(.{1,'.$charsPerLine.'})/', "$1$3\n", $text);
	}
	$imCanvas->annotateImage($imdSettings, 0, 0, 0, $text);
}
/*.................................................................*/

Usage Example:

Code: Select all



[code]
$image = new Imagick();
$image->newImage(500, 200, 'transparent');
applyImage($image, 'http://www.imagemagick.org/discourse-server/download/file.php?avatar=2_1196458341.png');
applyImage($image, 'http://www.imagemagick.org/discourse-server/download/file.php?avatar=2_1196458341.png', 50, 50, 25, 40);
applyText($image, 'ImageMagick is free software delivered as a ready-to-run binary distribution or as source code that you may freely use, copy, modify, and distribute. Its license is compatible with the GPL. It runs on all major operating systems.', '/myfont/Arial.ttf', 12, 75, 50, 150, 100);

Re: Text functions

Posted: 2009-06-26T15:55:34-07:00
by robcolburn
A little more friendly

Code: Select all

/**
  * applyLayer
  * @param Imagick canvas - Imagick object to apply image to
  * @param mixed settings - settings to apply, given as an associative array
  *    int 'top'                 - x-coord to start layer (relative to canvas), default 0
  *    int 'left'                - y-coord to start layer (relative to canvas), default 0
  *    int 'width'               - width of layer, default remaining width of canvas
  *    int 'height'              - height of layer, default remaining width of canvas
  *    string 'text'             - text to apply
  *    string 'textAlign'        - direction of text left/center/right, default left
  *    string 'font'             - font name/path to font file, default Arial
  *    int 'fontSize'            - size of font, default 10
  *    string 'color'            - named-color or hex code, default '#000000'
  *    string 'backgroundColor'  - named-color or hex code, default '#000000'
  *    string 'backgroundImage'  - path/url to image file, default unused
  *    int 'backgroundPositionX' - x-coord to start image (relative to layer), default 0
  *    int 'backgroundPositionY' - x-coord to start image (relative to layer), default 0
  *    int 'scale'                - scale background image to width/height ? - default false
  * 
  * @example applyLayer($im, array('top'=>50,'left'=>50,'width'=>200,'height'=>100,'font'=>'/font/Arial.ttf','fontSize'->12,'color'=>'#ff0000','text'=>'A big long text string');
  * @example applyLayer($im, array('top'=>80,'left'=>80,'width'=>200,'height'=>100,'backgroundImage'=>'/path/to/image.jpg','scale'=>1);
  **/
function applyLayer($canvas, $settings) {
	$s = array('font'=>'Arial', 'fontsize'=>10, 'backgroundcolor'=>'transparent', 'backgroundimage'=>'', 'backgroundpositionx'=>0, 'backgroundpositiony'=>0, 'textalign'=>'left', 'top'=>0, 'left'=>0, 'width'=>0, 'height'=>0, 'scale'=>0, 'text'=>'');
	if (is_array($settings)) {
		foreach($settings as $k=>$v) $s[strtolower(str_replace('-','',$k))] = $v;
	}
	elseif (is_string()) {
		//css parsing
		$matches = array();
		preg_match_all("([\w\-]+)\s*:\s*([\#\w\\\/\.]+);?", $settings, $matches);
		for($i=0; $i<count($matches); $i++) $s[strtolower(str_replace('-','',$matches[$i][1]))] = $matches[$i][2];
	}
	$s['width'] = !empty($s['width']) ? $s['width'] : ($canvas->getImageWidth() - $s['left']);
	$s['height'] = !empty($s['height']) ? $s['height'] : ($canvas->getImageHeight() - $s['top']);
	
	//..process
	$layer = new Imagick();
	$layer->newImage($s['width'], $s['height'], new ImagickPixel($s['backgroundcolor']));
	if (!empty($s['backgroundimage'])) {
		$img = new Imagick();
		$img->readImageFile(fopen($s['backgroundimage'], 'rb'));
		if (!empty($s['scale'])) $img->cropThumbnailImage($s['width'], $s['height']);
		$layer->compositeImage($img, Imagick::COMPOSITE_OVER, $s['backgroundpositionx'], $s['backgroundpositiony']);
		$img->destroy();
	}
	if (!empty($s['text'])) {
		$font = new ImagickDraw();
		$font->setFont($s['font']);
		$font->setFontSize($s['fontsize']);
		$font->setFillColor(new ImagickPixel($s['color']));
		$grav = array('right'=>Imagick::GRAVITY_NORTHEAST, 'center'=>Imagick::GRAVITY_NORTH, 'left'=>Imagick::GRAVITY_NORTHWEST);
		$font->setGravity($grav[$s['textalign']]);
		//..wordwrap
		$metrics = $layer->queryFontMetrics($font, $s['text']);
		if ($metrics["textWidth"] > $s['width']) {
			$charsPerLine = floor($s['width'] / ($metrics["textWidth"] / strlen($s['text'])));
			$s['text'] = preg_replace('/(.{1,'.$charsPerLine.'})( +|$\n?)|(.{1,'.$charsPerLine.'})/', "$1$3\n", $s['text']);
		}
		$layer->annotateImage($font, 0, 0, 0, $s['text']);
		$font->destroy();
	}
	$canvas->compositeImage($layer, Imagick::COMPOSITE_DEFAULT, $s['left'], $s['top']);
	$layer->destroy();
	return $canvas;
}
/*.................................................................*/