Page 1 of 1

Multicolor text

Posted: 2008-06-11T17:36:00-07:00
by Romain
hello community,

I want to write a variable text using different colours. What I want is like the google logo.

I thought of just annotating the letters one by one but I need to know which position to start annotating the next letter from?
convert -size 400x150 xc:white -font Arial -pointsize 100 -annotate +20+95 "G" -annotate +100+95 "o" -annotate +160+95 "o" -annotate +220+95 "g" -annotate +280+95 "l" -annotate +340+95 "e" text.png
Or is there a better way to achieve this?

Note: For now, I use PHP with exec()

Thanks in advance for your help

Re: Multicolor text

Posted: 2008-06-11T18:31:56-07:00
by anthony
What you are wanting is to know the cursour forwarding value for each letter. The API can get this information directly from the font, but the command line does not have such direct access.

There are techniques for appending and/or figuring out the advancement amount (which is usualy the same as the undercolor box width) See IM examples...
Determining Font Metrics, without using an API
http://imagemagick.org/Usage/text/#font_info

If the font is well behaved, you can just generate a label: for each character, and append them together. As long as the same font and font size is use they should fit together correctly. Otherwise you will have to resort to some very fancy techniques as described in
Creating Lines of Mixed Font Styles
http://imagemagick.org/Usage/text/#mixed_font_lines

Re: Multicolor text

Posted: 2008-06-12T00:06:35-07:00
by Bonzo
You could use something like

Code: Select all

<?php
exec("convert -size 30x30 xc:white -font ../fonts/verdana.ttf -fill black -pointsize 30 -gravity center -draw \" text 0,0 'R' \" R.gif");
exec("convert -size 30x30 xc:black -font ../fonts/verdana.ttf -fill white -pointsize 30 -gravity center -draw \" text 0,0 'u' \" u.gif");
exec("convert -size 30x30 xc:white -font ../fonts/verdana.ttf -fill black -pointsize 30 -gravity center -draw \" text 0,0 'b' \" b.gif");
exec("convert -size 30x30 xc:black -font ../fonts/verdana.ttf -fill white -pointsize 30 -gravity center -draw \" text 0,0 'b' \" bb.gif");
exec("convert -size 30x30 xc:white -font ../fonts/verdana.ttf -fill black -pointsize 30 -gravity center -draw \" text 0,0 'l' \" l.gif");
exec("convert -size 30x30 xc:black -font ../fonts/verdana.ttf -fill white -pointsize 30 -gravity center -draw \" text 0,0 'e' \" e.gif");
exec("convert -size 30x30 xc:white -font ../fonts/verdana.ttf -fill black -pointsize 30 -gravity center -draw \" text 0,0 'w' \" w.gif");
exec("convert -size 30x30 xc:black -font ../fonts/verdana.ttf -fill white -pointsize 30 -gravity center -draw \" text 0,0 's' \" s.gif");
exec("convert -background white -bordercolor black -border 1 -gravity Center R.gif u.gif b.gif bb.gif l.gif e.gif w.gif e.gif b.gif s.gif +append text_bw.jpg");

// Delete the tempory images 

$delete = array('R.gif','u.gif','b.gif','bb.gif','l.gif','e.gif','w.gif','s.gif'); 
foreach ($delete as $value) { 
    unlink($value); }
    
?> 
This is an old example and could probably be condensed quite a bit.

Image

Re: Multicolor text

Posted: 2008-06-12T04:51:04-07:00
by Romain
Thanks for your detailed answers it's much appreciated!

As I am still discovering ImageMagick, I didn't want to dive too quickly into the APIs but I guess I will if I want to achieve my goal! ;)

By the way I'd like to thank you a lot for all your examples Anthony, it's an amazing resource for the beginner!

Bonzo has some fantastic examples as well, especially this one.
But the code is a little outdated for the new PHP versions, so I corrected this and added the "$path" variable because on my server, for some reason some of the commands didn't work because I was calling "convert" and not "/usr/local/bin/convert"...

Code: Select all

<?php 
/*
Source: http://www.rubblewebs.co.uk./imagemagick/examples/example_b.php
Note: Some care needs using on how to divide the image as sometimes a small image is created
that causes a problem.
*/

// Absolute path to the generated images without the trailing slash
$path = "/var/www/vhosts/domain.com/httpdocs";


// If the form has been submitted do this
if ( @$_POST['Submit'] ) { 

// Temporary upload image name
$image = $_FILES['filename']['tmp_name'];

// Name to save the image as - in this case the same as the original
$new_image = $path.'/'.$_FILES['filename']['name'];

// Amount of images in x
$qty_x = $_POST['x'];

// Amount of images in y
$qty_y = $_POST['y'];

// Get the size of the original image
$size = getimagesize($image);

// Size to crop the images to
$crop_x = round( $size[0]/$qty_x);
$crop_y = round( $size[1]/$qty_y);

// Canvas for combined images - it will be trimmed to the finished image size in the code
$width = ( $size[0] * 1.5 );
$height = ( $size[1] *1.5 );

// Crop the image
system("/usr/local/bin/convert $image -crop {$crop_x}x{$crop_y} $path/image-%d.jpg"); 


// Remove the .jpg from the filenames
foreach (glob("$path/*.jpg") as $filename) {
$file = str_replace('.jpg', '', $filename );
system("/usr/local/bin/convert $filename -background black +polaroid $file.png"); 
}

// Set $command variable
$command = "";

// Loop through generating the image layout
for ($j = 0; $j < $qty_y; $j++) { 

  for ($i = 0; $i < $qty_x; $i++) {    $n = $j>0 ? $qty_x*($j)+$i : $i; 
  $offset_x= ( ($crop_x * $i ) + rand(2, 25));
  $offset_y=( ($crop_y * $j ) + rand(2, 25));
  $command .= " $path/image-$n.png -geometry +$offset_x+$offset_y -composite" ;  } 
  }

// Produce the combined image
system ( "/usr/local/bin/convert -size {$width}x{$height} xc:silver $command -trim $new_image"); 

// Delete tempory images
foreach (glob("$path/*.jpg") as $filename) {
if($filename != $new_image) unlink($filename); 
}
foreach (glob("$path/*.png") as $filename) {
if($filename != $new_image) unlink($filename); 
}


// Output the image to the browser
header( 'Content-Type: image/png' );
readfile("$new_image");
}
else { ?>
<form method="post" action="" enctype="multipart/form-data"> 
<label>File to upload:</label>
<input type="file" name="filename"  /><br />
<label>Amount of images in X</label>
<input type="text" name="x">
<label>Amount of images in Y</label>
<input type="text" name="y">
<input type="Submit" name="Submit" value="Submit" />
</form>
 <?php } ?>

Re: Multicolor text

Posted: 2008-06-12T11:27:00-07:00
by Bonzo
Thanks for the coments Romain; I am actualy looking at improving some of my code now along with my whole site.
There are useful snippets of information not being found and even I can not find them again!

Did you notice this on my site:

Code: Select all

To make the code more portable you can use this to get the path to convert from the server and automaticaly put it into your code.

<?php
// In my case $HTTP_ENV_VARS['PATH'] = bin:usr/bin
$env_vars = explode( ':', $HTTP_ENV_VARS['PATH']);
// Combine the required part from $HTTP_ENV_VARS['PATH'] and convert for your path.
$env_path = $env_vars[1]."/convert";
// Now $env_path = usr/bin/convert

// Use like:
exec("$env_path image.jpg -resize 100x100 output.jpg");
?> 

Re: Multicolor text

Posted: 2008-06-12T16:25:04-07:00
by anthony
Bonzo, I do not think that method of path to 'convert' is very portable. It will probably work for Linux and MacOSX, but for other UNIX systems it will probably be wrong. It may as well have been equivalent to
$env_path = "/usr/bin/convert"
For example I know a lot of users install their own version of IM in their homes either because the system does not have one, OR the system one is too old.