Adding Color Gradient to Text in ImageMagick

Just starting with ImageMagick after having used GD Library for decades and so far ImageMagick is far, far easier! However, I can’t seem to create a horizontal gradient in the first block in the code below. I would like it to start with medium gray and move to deep red but I’m not sure even how to begin.

The code is in three parts. The first contains the ImageMagick bits and it’s the first block with $Font1 where I want to do the gradient. The second file contains the variables and here you may have to use fonts on your system and adjust accordingly if trying it out. The third simply loads it into the browser for viewing so if all are placed together into a single folder, they should work for testing purposes. The last bit has a snippet in it which, if unremarked, will let you see your available fonts.

I understand what it needs in general but all attempts to do it give either an error or nothing at all so how do I proceed?

show_logo.php

<?php

// SPECIFY CONFIGURATION FILE TO LOAD
include_once("params.php");

try {
	$image = new Imagick();
	$image->newImage($Width, $Height, new ImagickPixel($Background));

	$draw = new ImagickDraw();

	// SETTINGS AND SPECIFICATIONS FOR FIRST FONT
	if (isset($Font1) && $Font1 !== "") :
		$draw->setFont($Font1);
		$draw->setFontSize($Points1);
		$draw->setTextInterlineSpacing($LineSpace1);
		$draw->setTextKerning($Kerning1);
		$draw->setFillColor(new ImagickPixel($Color1));

		// ADDED FOR HORIZONTAL GRADIENT - NOT WORKING
		$gradient = new Imagick();
		$gradient->newPseudoImage($Width1, $Height1, "gradient:$StartColor1-$EndColor1");
		$draw->pushPattern('gradient_pattern', 0, 0, $Width1, $Height1);
		$draw->composite(Imagick::COMPOSITE_OVER, 0, 0, $Width1, $Height1, $gradient);
		$draw->popPattern();
		$draw->setFillPatternURL('#gradient_pattern');

		$image->annotateImage($draw, $PositionX1, $PositionY1, $Rotation1, $Text1);
	endif;

	// SETTINGS AND SPECIFICATIONS FOR SECOND FONT
	if (isset($Font2) && $Font2 !== "") :
		$draw->setFont($Font2);
		$draw->setFontSize($Points2);
		$draw->setTextInterlineSpacing($LineSpace2);
		$draw->setTextKerning($Kerning2);
		$draw->setFillColor(new ImagickPixel($Color2));
		$image->annotateImage($draw, $PositionX2, $PositionY2, $Rotation2, $Text2);
	endif;

	// SETTINGS AND SPECIFICATIONS FOR THIRD FONT
	if (isset($Font3) && $Font3 !== "") :
		$draw->setFont($Font3);
		$draw->setFontSize($Points3);
		$draw->setTextInterlineSpacing($LineSpace3);
		$draw->setTextKerning($Kerning3);
		$draw->setFillColor(new ImagickPixel($Color3));
		$image->annotateImage($draw, $PositionX3, $PositionY3, $Rotation3, $Text3);
	endif;

	$image->setImageFormat('png');
	header('Content-Type: image/png');
	echo $image;

} catch (ImagickException $e) {
	echo 'Error: ' . $e->getMessage();
}

?>

params.php

<?php

// BEGIN SETUP
	$Size =	[
					"Width"	=> 400,
					"Height"	=> 80
					];

	// DEFINE TRUETYPE FONTS
	$Fonts =	[
					"Font1"			=> 'Arial-Bold',
					"Color1"			=> '#AA6B39',	// GOLDEN
					"StartColor1"		=> '#808080',		// HTML GRAY FOR HORIZONTAL GRADIENT
					"EndColor1"		=> '#800000',		// MAROON FOR HORIZONTAL GRADIENT
					"Points1"			=> 48,
					"LineSpace1"	=> 0,
					"Kerning1"		=> -2,
					"PositionX1"		=> 0,
					"PositionY1"		=> 50,
					"Rotation1"		=> 0,

					"Font2"			=> 'AvantGarde-Book',
					"Color2"			=> '#F9F9F9',		// OFF WHITE
					"Points2"			=> 18,
					"LineSpace2"	=> -8,
					"Kerning2"		=> -1,
					"PositionX2"		=> 225,
					"PositionY2"		=> 35,
					"Rotation2"		=> 0,

					"Font3"			=> 'Andale',
					"Color3"			=> '#FFFFF4',		// OFF WHITE
					"Points3"			=> 14,
					"LineSpace3"	=> 0,
					"Kerning3"		=> 0,
					"PositionX3"		=> 150,
					"PositionY3"		=> 70,
					"Rotation3"		=> 0
					];

	// DEFINE BACKGROUND COLOR
	$Colors =	[
						"Background"	=> 'black'
						];

	// DEFINE TEXTS FOR EACH FONT
	$Texts =	[
					"Text1" => 'Site Name',
					"Text2" => "Some text here           \n . . . continues here", // MUST HAVE DOUBLE QUOTES FOR LINE BREAK
					"Text3" => 'This is test text to fill the third value'
					];

	// TEXT POSITIONS REFERENCE NOTES
	// $image->annotateImage($draw, [X], [Y], [Angle], [Text])
	// X - Horizontal offset in pixels from the left edge
	// Y - Vertical offset in pixels from top to the baseline of text. If set to 0, text will be above the image
	// Angle - The angle at which to write the text
	// Text - The text string to draw

	$Values = array_merge($Size, $Fonts, $Colors, $Texts);

	// CREATE VARIABLES FROM MERGED VALUES ARRAY
	foreach ($Values as $key => $val) :
		$$key = $val;
	endforeach;
// END SETUP

?>

viewer.php

<?php

/* $fontList = \Imagick::queryFonts('*');
foreach ( $fontList as $fontName ) :
	echo $fontName . '<br>';
endforeach; */

echo "<img src=\"show_logo.php\">";

?>

No ideas? I’m hoping to do it in such a way that it is within a block as I showed in the question so that I can wrap a conditional around it to enable or disable at will by providing or not providing the gradient colors. I managed to get a gradient working by itself but not sure how to integrate it into my existing code without breaking it.

Also, this example has the gradient top to bottom when I want it left to right. I added the code to do so, $gradient->setOption('gradient:angle', '90'); , but it made no difference.

// SPECIFY CONFIGURATION FILE TO LOAD
include_once("params.php");

// CREATE THE GRADIENT IMAGE
$gradient = new Imagick();

// CREATE A LINEAR GRADIENT FROM LEFT TO RIGHT
$gradient->newPseudoImage($Width, $Height, "gradient:$StartColor1-$EndColor1");
$gradient->setOption('gradient:angle', '90'); 

// CREATE THE IMAGICKDRAW OBJECT
$draw = new ImagickDraw();
$draw->setFont($Font1);
$draw->setFontSize($Points1);

// USE THE GRADIENT IMAGE AS THE FILL PATTERN
// PUSH THE GRADIENT IMAGE INTO THE DRAW PATTERN
$draw->pushPattern('gradient_pattern', 0, 0, $Width, $Height);
$draw->composite(Imagick::COMPOSITE_OVER, 0, 0, $Width, $Height, $gradient);
$draw->popPattern();

// SET THE FILL TO USE THE PATTERN
$draw->setFillPatternURL('#gradient_pattern');

// ANNOTATE THE TEXT ONTO A NEW CANVAS
$image = new Imagick();
$image->newImage($Width, $Height, $Background);

$draw->annotation($PositionX1, $PositionY1, $Text1);

// DRAW THE IMAGICKDRAW OBJECT ONTO THE CANVAS
$image->drawImage($draw);

// OUTPUT THE IMAGE
$image->setImageFormat('png');
header('Content-Type: image/png');
echo $image;

Replying to myself that it is now working. Of course, it could probably use some streamlining especially in the $Font1 section where the gradient bit uses annotation() while the non-gradient bit uses annotateImage(). I don’t see how to use annotateImage() for both.

I also added "Angle" => 90, to the fonts array in params.php in case it needs to be set differently in other uses.

try {
	$image = new Imagick();
	$draw = new ImagickDraw();

	if (isset($Font1) && $Font1 !== "") :
		// CREATE THE IMAGICK DRAW OBJECT
		$draw->setFont($Font1);
		$draw->setFontSize($Points1);
		$draw->setTextInterlineSpacing($LineSpace1);
		$draw->setTextKerning($Kerning1);
		
		// IF ENABLED, PREPARE GRADIENT
		if ((isset($StartColor1) && $StartColor1 !== "") && (isset($EndColor1) && $EndColor1 !== "")) :
			// CREATE THE GRADIENT IMAGE
			$gradient = new Imagick();

			// SET GRADIENT LEFT TO RIGHT
			$gradient->setOption('gradient:angle', $Angle);

			// CREATE THE LINEAR GRADIENT
			$gradient->newPseudoImage($Width, $Height, "gradient:$StartColor1-$EndColor1");

			// USE THE GRADIENT IMAGE AS THE FILL PATTERN
			// PUSH THE GRADIENT IMAGE INTO THE DRAW PATTERN
			$draw->pushPattern('gradient_pattern', 0, 0, $Width, $Height);

			$draw->composite(Imagick::COMPOSITE_OVER, 0, 0, $Width, $Height, $gradient);
			$draw->popPattern();

			// SET THE FILL TO USE THE PATTERN
			$draw->setFillPatternURL('#gradient_pattern');

			// ANNOTATE THE TEXT ONTO A NEW CANVAS
			$image->newImage($Width, $Height, $Background);
			$draw->annotation($PositionX1, $PositionY1, $Text1);

			// DRAW THE IMAGICK DRAW OBJECT ONTO THE CANVAS FOR FIRST FONT WITH GRADIENT
			$image->drawImage($draw);
	
			// CLEAR GRADIENT OBJECT
			$gradient->clear();
		else :
			$image->newImage($Width, $Height, new ImagickPixel($Background));
			$draw->setFillColor(new ImagickPixel($Color1));
			
			// DRAW THE IMAGICK DRAW OBJECT ONTO THE CANVAS FOR FIRST FONT WITHOUT GRADIENT
			$image->annotateImage($draw, $PositionX1, $PositionY1, $Rotation1, $Text1);
		endif;
	endif;

	// SETTINGS AND SPECIFICATIONS FOR SECOND FONT
	if (isset($Font2) && $Font2 !== "") :
		$draw->setFont($Font2);
		$draw->setFontSize($Points2);
		$draw->setTextInterlineSpacing($LineSpace2);
		$draw->setTextKerning($Kerning2);
		$draw->setFillColor(new ImagickPixel($Color2));
		
		// DRAW THE IMAGICK DRAW OBJECT ONTO THE CANVAS FOR SECOND FONT
		$image->annotateImage($draw, $PositionX2, $PositionY2, $Rotation2, $Text2);
	endif;

	// SETTINGS AND SPECIFICATIONS FOR THIRD FONT
	if (isset($Font3) && $Font3 !== "") :
		$draw->setFont($Font3);
		$draw->setFontSize($Points3);
		$draw->setTextInterlineSpacing($LineSpace3);
		$draw->setTextKerning($Kerning3);
		$draw->setFillColor(new ImagickPixel($Color3));
		
		// DRAW THE IMAGICK DRAW OBJECT ONTO THE CANVAS FOR THIRD FONT
		$image->annotateImage($draw, $PositionX3, $PositionY3, $Rotation3, $Text3);
	endif;

	$image->setImageFormat('png');
	header('Content-Type: image/png');
	echo $image;

	$draw->clear();
	$image->clear();

} catch (ImagickException $e) {
	echo 'Error: ' . $e->getMessage();
}
Sponsor our Newsletter | Privacy Policy | Terms of Service