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 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., \'.
Other clean up issues?
cheers,
gary
.
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
A couple of comments
I am glad you found this code useful Gary
1/ You have broken your own code as you have modified it to
That will not work for me but this will
2/
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
I am glad you found this code useful Gary
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.
1/ You have broken your own code as you have modified it to
That will not work for me but this will
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.
2/
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.
I would prefer to follow your lead, but threw an error at
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:
has been replaced by the following:
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?
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