I've had a little project on the back burner for quite a while. It's really for my design associate, so it's not something I really know much about; graphics. The ultimate goal is to take a bit of text, and turn it into a tricked up, glowing, lined, and drop shadowed image with an alpha channel. For getting my feet wet, I'll settle for making an image of the font's name, in that font face.

Now any of you graphic whiz-bangs can open up Photoshop or the GIMP, and go to town. The issue is, how do you automate it? Imagick is a native PHP API for ImageMagick, but lacks the power and versatility of ImageMagick. ImageMagick is a suite of graphics utilities that run from the command line interface (CLI), making it perfect for scripting. I hear some of you groaning, "there he goes with that CLI stuff again." You know who you are, Duckie. Face it, if you're going to script, you're going to use the CLI, if only by proxie.

If I were scripting this to run as a local application, I'd probably use Bash, a touch of AWK, and ImageMagick. PERL might even be a better choice, but I'm not all that comfortable in that language. Since I want a web app, I decided on PHP as the thin glue to hold things together.

This first little baby step has a practical use. I'm going to first get a list of all the fonts on the server. IM has a command to get the list, "convert -list font" (older versions of IM use "type" as the argument). You didn't know it was that easy, did you? How many licks does it take 'til you get to the mid… Oh, wait, that's Li'l Kim. How many clicks to open every font file and extract the meta-data for the list? The listing looks like this:

Name                             Family                 Style   Stretch   Weight
--------------------------------------------------------------------------------
AvantGarde-Book                  AvantGarde             Normal  Normal       400
AvantGarde-BookOblique           AvantGarde             Oblique Normal       400
AvantGarde-Demi                  AvantGarde             Normal  Normal       600
AvantGarde-DemiOblique           AvantGarde             Oblique Normal       600
Bookman-Demi                     Bookman                Normal  Normal       600
Bookman-DemiItalic               Bookman                Italic  Normal       600
Bookman-Light                    Bookman                Normal  Normal       300
Bookman-LightItalic              Bookman                Italic  Normal       300
Courier                          Courier                Normal  Normal       400
Courier-Bold                     Courier                Normal  Normal       700
Courier-BoldOblique              Courier                Oblique Normal       700
Courier-Oblique                  Courier                Oblique Normal       400
fixed                            Helvetica              Normal  Normal       400
Helvetica                        Helvetica              Normal  Normal       400
Helvetica-Bold                   Helvetica              Normal  Normal       700
Helvetica-BoldOblique            Helvetica              Italic  Normal       700
Helvetica-Narrow                 Helvetica Narrow       Normal  Condensed    400
Helvetica-Narrow-Bold            Helvetica Narrow       Normal  Condensed    700
:
The first column is the name of the font. You need this because unlike html, scripts can't apply a stylesheet to determine whether you want Roman or Italic, bold or normal. The second column is the family name, which we do use in html. The next column is the style, followed by the stretch, then the weight.

The script will send the list to the browser as text. (Not to be confused with pretext. e.g. "I'm the last surviving son of Prince …".)

Next, we clean the array up a bit, and select only the first column to work with. Now, it's back to the CLI command; the script executes the convert utility with arguments to draw the name of the font, using that font.

The end result is an image of each font on your machine. I don't know about you, but I've always wondered what those fonts with the silly names actually looked like. I also add the font-name in plain text, because some of those I have just aren't readable fonts.

This script generated 628 images in 31 seconds on my machine. Call it twenty images per second. Match that in Photoshop.

The script is mostly stolen with permission, and lightly modified by myself. Some of it seems a bit clumsy, so if you can contribute toward increased elegance, go for it. All comments welcome.

To run, you must have PHP, with safe mode off, and ImageMagick.

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xml:lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      lang="en">
<head>
  <meta name="generator"
        content=
        "HTML Tidy for Linux (vers 7 December 2008), see <a href="http://www.w3.org" rel="nofollow">www.w3.org</a>" />
 
  <title>Make font images</title>
  <meta http-equiv="content-type"
        content="text/html; charset=utf-8" />
  <meta name="author"
        content="Gary Turner" />
  <meta name="Creation date"
        content="24 March, 2009" />
  <style type="text/css">
/*<![CDATA[*/
 
  body {
    background-color: white;
    color: black;
    font: 100% sans-serif;
    }
 
  p {
    font-size: 1em;
    }
 
  /*]]>*/
  </style>
</head>
 
<body>
  <?php
 
  /****** This script was mostly lifted from <a href="http://www.rubblewebs.co.uk" rel="nofollow">www.rubblewebs.co.uk</a>.  I
  modified it to run in my server's installation, Debian Squeeze
  (testing) Gnu/Linux.  There were differences in the array formats that
  had to be dealt with.  The original also cleaned up its own messes by
  deleting the images after use.  This version does not, as there are
  parsing errors that I haven't figured out.  ******/
 
  /****** The first section simply runs "convert -list font" from the
  system command, and prints out the results.  This is all the
  registered fonts on your system. The top list are those that are
  part of the ImageMagick suite.  The rest are those found at various
  places on your system. ******/
 
      // Select the version number from the configeration file
  preg_match('/^LIB_VERSION_NUMBER ([0-9,]+)$/m', shell_exec("convert -list configure "), $vnums);
 
      // Seperate the numbers at the ,
  $number = explode( ",", $vnums[1] );
 
      // Format the version from 6,3,4,1 format to 06030401
  $version = "";
 
  for($i=0;$i<4;$i++) {
     $version .= str_pad( $number[$i], 2, '0', STR_PAD_LEFT );
  } 
 
      // The 'list' method used to get the fonts changed in IM v6.3.5-7
  $font_list = ( $version > "06030507" ) ? "font" : "type";
 
  // Display the version of Imagemagick, the method to read the fonts and the list of fonts
  echo "<h2>IM version: ".$version." </h2>\n
  <h3>Method used: convert -list $font_list</h3>\n
  <hr>\n<pre>";
      system("convert -list $font_list");
      echo "</pre>\n<hr>";
 
  /****** This section takes the array found above and strips out the
  first column as the canonical name of each font.  It uses that name as
  the font-name to call, the text of the image made, and as the alt text
  of the image. ******/
 
  echo "<ol>\n"; // this closes after the list is done at the end
 
  // Populate the array only - do not display it
    exec("convert -list $font_list", $IMarray, $code);
 
  // Sort the array alphabeticly
    sort( $IMarray );
 
  // Setup some default values
    $delete = array();
    $image_list = "";
 
  // Function to remove items from array
    function array_delete( $array, $filterfor ){ 
       $thisarray = array (); 
       foreach( $array as $value ) 
       if( stristr( $value, $filterfor )===false && strlen( $value )>0) 
          $thisarray[] = $value; 
       return $thisarray; 
    } 
 
  // Remove items containing Name from the arrary
    $NoName = array_delete( $IMarray, "Name" ); 
 
  // Remove items containing Path: from the array
    $NoPath = array_delete( $NoName, "Path:" ); 
 
  // Remove items containing Path: from the array
    $NoFamily = array_delete( $NoPath, "family:" );
 
  // Remove items containing Path: from the array
    $NoStretch = array_delete( $NoFamily, "stretch:" );
 
  // Remove items containing Path: from the array
    $NoWeight = array_delete( $NoStretch, "weight:" );
 
  // Remove items containing Path: from the array
    $NoStyle = array_delete( $NoWeight, "style:" );
 
  // Find the amount of items in the array
    $count = count( $NoStyle );
 
  // Start the loop to generate the images
    for ( $i=2; $i<$count; $i++ ) {
 
  // Get the font name from the array
    $FirstPart = explode(' ', $NoStyle[$i]);
    $Font = str_replace( ' ', '', $FirstPart['0']);   
    $Image = $Font.".png";   
 
  // Create the images
    $cmd = "-size 500x30 xc:lightblue -font $Font -pointsize 20 -draw \"gravity center fill black text 0,0 $Font \" ";
 
    exec("convert $cmd $Image");
 
    echo "<li><img src='$Image' alt='$Font' /> $Font </li>\n";
    }
 
    echo "</ol>";
 
  ?>
</body>
</html>

cheers,

gary

bug list #1

I have noticed the script fails to make images of font names that include an apostrophe, "'". Why anyone would use that is beyond me; font makers are graphics people, ∴ weird. :shrug:

The apostrophe breaks the quoted text values. I will need to scrub $Font by escaping the single quote, i.e., \'.

// Get the font name from the array
    $FirstPart = explode(' ', $NoStyle[$i]);
    $Font = str_replace( ' ', '', $FirstPart['0']);   
    $Image = $Font.".png";  

Other clean up issues?

cheers,

gary

.

Quote:

I hear some of you groaning, "there he goes with that CLI stuff again." You know who you are, Duckie.

ROFL!!!!

This is not a laughing matter. Harrumph!

So get off the floor, install ImageMagick, and run the script.

cheers,

gary

Not likely! I'm fighting

Laughing out loud Not likely! I'm fighting enough fires of my own to start playing with yours. Wink

A couple of comments

I am glad you found this code useful Gary Wink

1/ You have broken your own code as you have modified it to

  // Get the font name from the array
    $FirstPart = explode(':', $NoStyle[$i]);
    $Font = str_replace( ' ', '', $FirstPart['0']);   
    $Image = $Font.".png";

That will not work for me but this will
  // Get the font name from the array
    $FirstPart = explode(' ', $NoStyle[$i]);
    $Font = str_replace( ' ', '', $FirstPart['1']);   
    $Image = $Font.".png"; 

2/

Quote:

The original also cleaned up its own messes by deleting the images after use.

I made one large image out of all my small images then deleted them rather than use the small ones you did; I think your layout looks nicer but has more files.

3/ Some fonts return ???? as the image; I pressumed this must be down to the charset used but am not sure.

Bonzo wrote:I am glad you

Bonzo wrote:

I am glad you found this code useful Gary Wink

Ah, welcome to CSSCreator. I'm glad and surprised you found us. I apologize for not offering a more direct credit, and a link to the original; I had misplaced the link when writing the article. That, I can remedy now: Server - Your installed fonts.

Quote:

1/ You have broken your own code as you have modified it to

  // Get the font name from the array
    $FirstPart = explode(':', $NoStyle[$i]);
    $Font = str_replace( ' ', '', $FirstPart['0']);   
    $Image = $Font.".png";

That will not work for me but this will
  // Get the font name from the array
    $FirstPart = explode(' ', $NoStyle[$i]);
    $Font = str_replace( ' ', '', $FirstPart['1']);   
    $Image = $Font.".png"; 

For whatever reason, on my install, the separator is a space rather than a colon, and the list/array is zero based instead of starting at one. Is this a MSFT vs *Nix thing? When the first trial, after correcting the separator, gave me the font family instead of font name, it was obvious I needed the zeroth part in Linux.

Quote:

2/

Quote:

The original also cleaned up its own messes by deleting the images after use.

I made one large image out of all my small images then deleted them rather than use the small ones you did; I think your layout looks nicer but has more files.

Just imagine if I had thousands of fonts, instead of only 628. Smile I would prefer to follow your lead, but threw an error at

// Delete the tempory images
    foreach ( $delete as $value ) { 
        <span style="color:red">unlink( $value );</span> }
So I bypassed that whole section, pending a bit more study.

Quote:

3/ Some fonts return ???? as the image; I pressumed this must be down to the charset used but am not sure.

I didn't get that, but did get a blank image (bg only) on a wingdings font. Font names that include a single quote or apostrophe ('), or a reserved entity such as an ampersand (&) fail due to breaking the function's argument or breaking the html. These reserved characters will require being escaped.

Thank you for this script, and the other great examples on your site. A CLI based suite of utilities like ImageMagick's puts an amazing amount of power in our hands, to be exercised with fairly simple scripting to glue the pieces together.

cheers,

gary

Thanks for the comments

I have Google alerts set to tell me when it finds anything new containing Imagemagick and it must have found your article withing a day or so of you posting; it has taken me this long to read it.

As I say I am glad you found a use for it; I get no feedback from people visiting my site about the code I have posted and so I do not know if it works or not.
I started the site as I could not find any examples of Image magick and php use and have now included a few examples of Imagick, GD and some batch scripts.

From reading your post I have now found that there are at last two different outputs for the array used in the code and I am looking into changing the code to allow for that.

The code I find has trouble with some fonts and these tend to be ones not using Latin characters; I presume that the name of the font is in Latin but there are no equivalent character in the font and so it displays ??????
None of my fonts so far have anything other than alphabetic characters or – so far but I will look into that as well.

Imgemagick is very versatile and you can send it variables and so once you ave the code working you can send it options from a form or in the URL.

Anthony

I seem to get blank images

I seem to get blank images on the oddball fonts, e.g. Symbols.

I have uploaded the script to my site, make font images. Consider this url to be temporary.

This part:

 // Get the font name from the array
    $FirstPart = explode(' ', $NoStyle[$i]);
    $Font = str_replace( ' ', '', $FirstPart['0']);
    $Image = $Font.".png";

has been replaced by the following:
 // Get the font name from the array
    $FirstPart = explode(' ', $NoStyle[$i]);
    $Font = str_replace( ' ', '', $FirstPart['0']);
    $Font = str_replace('\'', '', $Font);
    $Font = str_replace('&', 'and', $Font);
    $Image = $Font.".png";
The two added lines remove any apostrophe, and replace the ampersand with "and" in font names.

cheers,

gary

Updated code

I pressume you are still modifying your code as the page link above keeps displaying differnt things !
I have put some updated code on this page: http://www.rubblewebs.co.uk/imagemagick/server/fonts.php It works for both different types of output I get on my localhost and server.

I will add your modification to my code when I get home.

Somehting like this?

<?php
        //http://www.joeri67.nl/boyism/clients/sweets/porcelain.php?line1=do%20you%20mean&line2=+something%20like%20this?&color=A83291
 
	$line1=$_REQUEST['line1'];
	$line2=$_REQUEST['line2'];
	$line3=$_REQUEST['line3'];
 
	$r= $_REQUEST['r'];	$g= $_REQUEST['g'];	$b= $_REQUEST['b'];
	if ($r == ""){ $r= 12; $g= 192; $b= 255; }
 
	$color= $_REQUEST['color'];
	if ($color != ""){ 
		$color = strtoupper( $color );
		$hex= "0123456789ABCDEF";
		$hr= substr( $color, 0, 2); 
		$hg= substr( $color, 2, 2);
		$hb= substr( $color, 4, 2);
		$r= strpos( $hex, substr( $hr, 0, 1) ) * 16 + strpos( $hex, substr( $hr, 1, 1) );
		$g= strpos( $hex, substr( $hg, 0, 1) ) * 16 + strpos( $hex, substr( $hg, 1, 1) );
		$b= strpos( $hex, substr( $hb, 0, 1) ) * 16 + strpos( $hex, substr( $hb, 1, 1) );
	}
 
 
	$font="./porcelain.ttf"; 
	$size= 40.0;
 
	$line= $line1;
	if( $line2 != "" ) $line= $line2;
	if( $line3 != "" ) $line= $line2;
 
	$src_add= singleLight( $line , $size , $font );
	$src_mul= singleDark ( $line , $size , $font );
 
	$src_im = singleColor( $line , $size , $font , $r, $g, $b );
 
	imageover($src_im, $src_add, $src_mul );
 
	$src_add= singleOut ( $line , $size , $font );
 
	imagecopymerge_alpha($src_add, $src_im, 0, 0, 0, 0, imagesx($src_im), imagesy($src_im), 100 );
	imagecopymerge_alpha($src_mul, $src_add, 0, 0, 0, 0, imagesx($src_im), imagesy($src_im), 100 );
 
	$font="./redensek.ttf";
 
	if ( $line2 != "" ){
		$top= shadeFont ( $line1 , 10.0 , $font );
		imagecopymerge_alpha($src_mul, $top, imagesx($src_mul)/2-imagesx($top)/2, 12, 0, 0, imagesx($top), imagesy($top), 100 );
	}
	if ( $line3 != "" ){
 
		$bot= shadeFont ( $line3 , 10.0 , $font );
		imagecopymerge_alpha($src_mul, $bot, imagesx($src_mul)/2-imagesx($bot)/2 , 38, 0, 0, imagesx($bot), imagesy($bot), 100 );
	}
 
	header("Content-type: image/png");
	imagepng($src_mul);
 
 
	imagedestroy($png);
	imagedestroy($src_mul);
	imagedestroy($src_add);
	imagedestroy($src_im);
	exit();
 
 
function shadeFont( $text, $size, $font )
{
	$box= calculateTextBox  ( $text, $font, $size, 0 );
 
	$png = imagecreatetruecolor($box['width']+2, $box['height']+4);
    imagesavealpha($png, true);
 
    $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127);
    imagefill($png, 0, 0, $trans_colour);
 
	$black = imagecolorallocate($png, 0, 0, 0);
	$white = imagecolorallocatealpha($png, 255, 255, 255, 0);
	$gray  = imagecolorallocatealpha($png, 0, 0, 0, 64);
 
	imagettftext( $png, $size, 0, 0, $size-2, $gray, $font, $text );
	imagettftext( $png, $size, 0, 2, $size-2, $gray, $font, $text );
	imagettftext( $png, $size, 0, 0, $size-0, $gray, $font, $text );
	imagettftext( $png, $size, 0, 2, $size-0, $gray, $font, $text );
 
	imagettftext( $png, $size, 0, 1, $size-2, $black, $font, $text );
	imagettftext( $png, $size, 0, 1, $size-0, $black, $font, $text );
	imagettftext( $png, $size, 0, 0, $size-1, $black, $font, $text );
	imagettftext( $png, $size, 0, 2, $size-1, $black, $font, $text );
 
	$over= imagefillttftext( $size, $font, $text, $font );
 
	// imagettftext( $png, $size, 0, 1, $size-1, $white, $font, $text );
 
	imagecopy($png, $over, 0, 0, 0, 0, imagesx($png), imagesy($png) );
 
	imagesavealpha($png, true);
 
	return $png;	
}
 
function imagefillttftext ( $size, $font, $text, $font )
{
	$box= calculateTextBox  ( $text, $font, $size, 0 );
 
	$png = imagecreatetruecolor($box['width']+2, $box['height']+4);
    imagesavealpha($png, true);
 
    $gray = imagecolorallocatealpha($png, 127, 127, 127, 0);
	$black = imagecolorallocate($png, 0, 0, 0);
	$trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127);
    imagefill($png, 0, 0, $gray);
 
	imagettftext( $png, $size, 0, 1, $size-1, $black, $font, $text );
 
	$fill = imagecreatetruecolor(imagesx($png), imagesy($png) );
	imagesavealpha($fill, true);
 
	for($y= 2; $y< imagesy($png); $y++){
		$i= ($y-3) * 10;
	 	$color = imagecolorallocatealpha($png, 255 - $i, 255 - $i, 255 - $i, 0);
  		imageline  ( $fill , 0 , $y , imagesx($png) , $y  , $color );
	}
 
	$mask = imagemask($fill, $png );
 
	return $mask;
 
}
 
 
function singleOut( $text, $size, $font )
{
   	$box= calculateTextBox  ( $text, $font, $size, 0 );
 
	$png = imagecreatetruecolor($box['width']+16, $box['height']+20);
    imagesavealpha($png, true);
 
    $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127);
    imagefill($png, 0, 0, $trans_colour);
 
	$black = imagecolorallocate($png, 0, 0, 0);
	$white = imagecolorallocatealpha($png, 255, 255, 255, 0);
	$gray  = imagecolorallocatealpha($png, 0, 0, 0, 64);
 
	imagettftext( $png, $size, 0, 0, $size-2, $gray, $font, $text );
	imagettftext( $png, $size, 0, 1, $size-2, $gray, $font, $text );
	imagettftext( $png, $size, 0, 0, $size-0, $gray, $font, $text );
	imagettftext( $png, $size, 0, 1, $size-0, $gray, $font, $text );
 
	imagettftext( $png, $size, 0, 1, $size-2, $black, $font, $text );
	imagettftext( $png, $size, 0, 1, $size-0, $black, $font, $text );
	imagettftext( $png, $size, 0, 0, $size-1, $black, $font, $text );
	imagettftext( $png, $size, 0, 2, $size-1, $black, $font, $text );
	imagesavealpha($png, true);
 
	return $png;	
}
 
function singleColor( $text, $size, $font, $r, $g, $b)
{
   	$box= calculateTextBox  ( $text, $font, $size, 0 );
 
	$png = imagecreatetruecolor($box['width']+16, $box['height']+20);
    imagesavealpha($png, true);
 
    $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127);
    imagefill($png, 0, 0, $trans_colour);
 
	$black = imagecolorallocate($png, 0, 0, 0);
	$white = imagecolorallocate($png, 255, 255, 255);
	$gray  = imagecolorallocate($png, 192, 192, 192);
	$color = imagecolorallocate($png, $r, $g, $b);
 
	imagettftext( $png, $size, 0, 1, $size-1, $color, $font, $text );
	imagesavealpha($png, true);
 
	return $png;	
}
 
function singleLight( $text, $size, $font)
{
   	$box= calculateTextBox  ( $text, $font, $size, 0 );
 
	$png = imagecreatetruecolor($box['width']+16, $box['height']+20);
    imagesavealpha($png, true);
 
//    $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127);
    $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 0);
 
	$black = imagecolorallocate($png, 0, 0, 0);
	$white = imagecolorallocate($png, 255, 255, 255);
	$gray  = imagecolorallocate($png, 192, 192, 192);
	$color = imagecolorallocate($png, $r, $g, $b);
	imagefill($png, 0, 0, $black);
 
	imagettftext( $png, $size, 0, 0, $size-2, $white, $font, $text );
	imagettftext( $png, $size, 0, 1, $size-1, $black, $font, $text );
	imagettftext( $png, $size, 0, 2, $size-0, $black, $font, $text );
	imagesavealpha($png, true);
 
	$png= imageMyBlur( $png, 2 );
	return $png;	
}
 
function singleDark( $text, $size, $font)
{
   	$box= calculateTextBox  ( $text, $font, $size, 0 );
 
	$png = imagecreatetruecolor($box['width']+16, $box['height']+20);
    imagesavealpha($png, true);
 
    $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127);
    imagefill($png, 0, 0, $trans_colour);
 
	$black = imagecolorallocate($png, 0, 0, 0);
	$white = imagecolorallocate($png, 255, 255, 255);
	$gray  = imagecolorallocate($png, 192, 192, 192);
	$color = imagecolorallocate($png, $r, $g, $b);
 
	imagettftext( $png, $size, 0, 2, $size-0, $black, $font, $text );
	imagettftext( $png, $size, 0, 1, $size-1, $white, $font, $text );
	imagettftext( $png, $size, 0, 0, $size-2, $white, $font, $text );
	imagesavealpha($png, true);
 
	$png= imageMyBlur( $png, 2 );
	return $png;	
}
 
 
function rescale( $src_image, $factor ){
 
	$src_w = imagesx( $src_image );
	$src_h = imagesy( $src_image );
 
	$dst_w= floor( $src_w * $factor );
	$dst_h= floor( $src_h * $factor );
 
	$dst_image= imagecreatetruecolor( $dst_w , $dst_h );
	imagesavealpha($dst_image, true);
	$trans_colour = imagecolorallocatealpha($dst_image, 0, 0, 0, 127);
    imagefill($dst_image, 0, 0, $trans_colour);
 
	imagecopyresampled ( $dst_image, $src_image  , 0 , 0 , 0 , 0 , $dst_w , $dst_h , $src_w , $src_h  );
 
	return $dst_image;
}
 
function calculateTextBox($text,$fontFile,$fontSize,$fontAngle) {
	$rect = imagettfbbox($fontSize,$fontAngle,$fontFile,$text);
 
	$minX = min(array($rect[0],$rect[2],$rect[4],$rect[6]));
	$maxX = max(array($rect[0],$rect[2],$rect[4],$rect[6]));
	$minY = min(array($rect[1],$rect[3],$rect[5],$rect[7]));
	$maxY = max(array($rect[1],$rect[3],$rect[5],$rect[7]));
 
	return array(
	"left"   => abs($minX),
	"top"    => abs($minY),
	"width"  => $maxX - $minX,
	"height" => $maxY - $minY,
	"box"    => $rect
	);
}
 
 
function imageMyBlur( $source_image, $amount ) {
        $temp_src = './temp_src.png';
        $temp_dst = './temp_dst.png';
		imagealphablending($source_image, false);
		imagesavealpha($source_image, true);
 
        if (!imagepng($source_image,$temp_src)){
            return false;
        }
		$pixcol= new ImagickPixel();
		$pixcol->setColorValue(imagick::COLOR_ALPHA , 0);
 
        $imagick = new Imagick();
        $imagick->readImage($temp_src);
		$imagick->setImageMatte( true );
 
  		$imagick->blurImage(0, $amount);
 
	    $imagick->writeImage($temp_dst);
 
	  	$result = imagecreatefrompng($temp_dst);
		imagesavealpha($result, true);
        unlink($temp_dst);
        unlink($temp_src);
        return $result;
}
 
function imagemask($src_im, $src_mask ){
 
    $w = imagesx( $src_im );
    $h = imagesy( $src_im );
 
	$dst_image= imagecreatetruecolor( $w , $h );
	imagesavealpha($dst_image, true);
	$trans_colour = imagecolorallocatealpha($dst_image, 0, 0, 0, 127);
	imagefill($dst_image, 0, 0, $trans_colour);
 
   	for( $x = 0; $x < $w; $x++ ){
        for( $y = 0; $y < $h; $y++ ){
            $colorxy    = imagecolorat( $src_im,  $x, $y );
            $colorxymsk = imagecolorat( $src_mask, $x, $y );
 
			$r_src= ( $colorxy >> 16 ) & 0xFF;
			$g_src= ( $colorxy >>  8 ) & 0xFF;
			$b_src= ( $colorxy       ) & 0xFF;
			$alpha= ( $colorxy >> 24 ) & 0xFF;
 
			$r_msk= ( $colorxymsk >> 8 ) & 0xFF;
 
			$alphacolorxy = imagecolorallocatealpha( $dst_image, $r_src,  $g_src,  $b_src, $r_msk );
 
			imagesetpixel( $dst_image, $x, $y, $alphacolorxy );
        }
    }
 
	return $dst_image;
 
} 
 
function imageover($src_im, $src_add, $src_mul ){
 
    $w = imagesx( $src_im );
    $h = imagesy( $src_im );
 
 
   	for( $x = 0; $x < $w; $x++ ){
        for( $y = 0; $y < $h; $y++ ){
            $colorxy    = imagecolorat( $src_im,  $x, $y );
            $colorxyadd = imagecolorat( $src_add, $x, $y );
            $colorxymul = imagecolorat( $src_mul, $x, $y );
 
			$r_src= ( $colorxy >> 16 ) & 0xFF;
			$g_src= ( $colorxy >>  8 ) & 0xFF;
			$b_src= ( $colorxy       ) & 0xFF;
			$alpha= ( $colorxy >> 24 ) & 0xFF;
 
			$r_add= ( $colorxyadd >> 8 ) & 0xFF;
			$r_mul= ( $colorxymul >> 8 ) & 0xFF;
 
			$r_src= $r_src / 255.0;
			$g_src= $g_src / 255.0;
			$b_src= $b_src / 255.0;
 
			$r_add= $r_add / 255.0;
			$r_mul= $r_mul / 255.0;
 
			$r_src= $r_src + $r_add * 1.8;
			$g_src= $g_src + $r_add * 1.8;
			$b_src= $b_src + $r_add * 1.8;
 
			$r_src= $r_src * $r_mul;
			$g_src= $g_src * $r_mul;
			$b_src= $b_src * $r_mul;
 
			if ( $r_src > 1.0 ){ $r_src= 1.0; }
			if ( $g_src > 1.0 ){ $g_src= 1.0; }
			if ( $b_src > 1.0 ){ $b_src= 1.0; }
 
			$r_src= ( $r_src * 255 ) & 0xFF;
			$g_src= ( $g_src * 255 ) & 0xFF;
			$b_src= ( $b_src * 255 ) & 0xFF;
 
 
            //get the color index with new alpha
            $alphacolorxy = imagecolorallocatealpha( $src_im, $r_src,  $g_src,  $b_src, $alpha );
 
			//set pixel with the new color + opacity
            imagesetpixel( $src_im, $x, $y, $alphacolorxy );
        }
    }
    // The image copy
 
	// imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
	// return src_im;
} 
 
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
    if(!isset($pct)){
        return false;
    }
    $pct /= 100;
    // Get image width and height
    $w = imagesx( $src_im );
    $h = imagesy( $src_im );
    // Turn alpha blending off
    imagealphablending( $src_im, false );
    // Find the most opaque pixel in the image (the one with the smallest alpha value)
    $minalpha = 127;
    for( $x = 0; $x < $w; $x++ )
    for( $y = 0; $y < $h; $y++ ){
        $alpha = ( imagecolorat( $src_im, $x, $y ) >> 24 ) & 0xFF;
        if( $alpha < $minalpha ){
            $minalpha = $alpha;
        }
    }
    //loop through image pixels and modify alpha for each
    for( $x = 0; $x < $w; $x++ ){
        for( $y = 0; $y < $h; $y++ ){
            //get current alpha value (represents the TANSPARENCY!)
            $colorxy = imagecolorat( $src_im, $x, $y );
            $alpha = ( $colorxy >> 24 ) & 0xFF;
            //calculate new alpha
            if( $minalpha !== 127 ){
                $alpha = 127 + 127 * $pct * ( $alpha - 127 ) / ( 127 - $minalpha );
            } else {
                $alpha += 127 * $pct;
            }
            //get the color index with new alpha
            $alphacolorxy = imagecolorallocatealpha( $src_im, ( $colorxy >> 16 ) & 0xFF, ( $colorxy >> 8 ) & 0xFF, $colorxy & 0xFF, $alpha );
            //set pixel with the new color + opacity
            if( !imagesetpixel( $src_im, $x, $y, $alphacolorxy ) ){
                return false;
            }
        }
    }
    // The image copy
    imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
} 
?>

Thanks for that, joeri67. I

Thanks for that, joeri67. I haven't really dug into imagick yet, so this will require a bit of study; also the general nature of the script will keep me busy digging into each function.

Being chicken-hearted as I am, I was going for a much more restrictive approach. That may change once I grok what you've done.

cheers,

gary