tobiasaries has asked for the wisdom of the Perl Monks concerning the following question:

I've been going bald the past few days trying to figure this out. I'm using Image::Magick to add text to a transparent image. The ultimate goal is to add some text to an image so that it looks exactly like this html text:

FONT COLOR="#FF0000" FACE="arial,helvetica,verdana" SIZE="1">Some Text Here

The problem here is that my resulting image looks like garbage. The image is squished, the text is too fat, the backgroud is grainy.

Here is what I've been playing with. I've experimented with all sorts of combos but still can't get it to work:

use Image::Magick; my $image = Image::Magick->new; my $fontdir= 'c:\winnt\fonts'; opendir FONTDIR, $fontdir; my @fonts = grep /arial.ttf$/, readdir FONTDIR; $image -> Set (size=>"320x20"); $image -> ReadImage("xc:white"); for my $font (@fonts) { $image -> Annotate( text => 'Test', stroke =>"#FF0000", strokewidth =>'1', style =>'normal', weight =>'1', x =>5, y =>15, pointsize=>12, antialias => 0, font =>"\@$fontdir\\$font"); } $image -> write ("jpg:test.jpg");

Replies are listed 'Best First'.
Re: Image::Magick ->Annotate Text
by seattlejohn (Deacon) on Jul 08, 2002 at 07:02 UTC
    Is there a reason you want to write this out as a JPEG file rather than a GIF or PNG? JPEG is a lossy compression scheme and usually does a really bad job of handling sharp borders, which includes things like text on a solid background. (Also, you mention transparency, but I don't believe JPEGs support such a concept.)

    As it happens, I was experimenting with the Annotate method myself just yesterday. This code worked fine for me:

    my $image = Image::Magick->new; $image->Set(size=>'300x300'); $image->ReadImage('xc:white'); $image->Annotate( font => 'c:/windows/fonts/arial.ttf', pointsize => 24, fill => 'green', text => "Image::Magick\nrocks dude", x => 100, y => 100 ); $image->Write('bigfont.gif');

    I'm not sure what might be wrong with your code, but I wonder if it could have anything to do with the font string you're passing to the Annotate method. For testing purposes, I would consider hardcoding the name of a font that you know is there.

    Hope this helps...

Re: Image::Magick ->Annotate Text
by grinder (Bishop) on Jul 08, 2002 at 07:11 UTC
    I don't see anything concrete, but here are several suggestions:

    • Not part of the problem, but you say 'c:\winnt\fonts'. This is better written as either 'c:\\winnt\\fonts' or 'c:/winnt/fonts'. I know you're using single quotes, so there are no meta-characters to escape, but it's just good practice.
    • You're not testing whether opendir succeeds or not (and you're not closing it afterwards)...
    • I forget what $image -> ReadImage("xc:white"); does exactly, paint the image white I assume. Try using a Draw with method => Floodfill and see what that does. Save the file out at this point, before writing the text, to test whether you really are getting a clean background, or whether it is adding the text that adds the garbage.
    • It looks like you're overwriting the same image with lots of different fonts, at least as many as there are whose names end in arial.ttf (and the dot is not escaped). Normally there should only be one, but you never know...
    • You're writing the image out in JPEG format, which is not the ideal format for non-photographic images. Try using PNG or GIF and see if that clears up the artifacts you observe.
    • The Image::Magick library is a cantankerous beast. I have installed it successfully on a couple of occasions, but I have also had a couple of times when I couldn't get it to behave correctly. See if what you are trying to do can be achieved with the command-line tools: that will at least help you find out whether the bug is in your Perl code (passing an incorrect parameter type) or something else.


    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'
Re: Image::Magick ->Annotate Text
by steves (Curate) on Jul 08, 2002 at 09:44 UTC

    Don't forget the ImageMagick lists. The authors are regulars and have helped me out with very specific advice that's helped several times.

    Ditto on the JPEG comment. I've used annotate with GIFs and gotten decent results.

    It's also not clear to me why you're iterating over fonts and writing the same text out for each one. That may be what's giving it the lousy appearance. I'd think you'd end up with "layered" annotations; each font on top of the other.

      Seattlejohn, Grinder, Steves, Thanks for your replies on this one. I got it to work exactly as I wanted. I also got rid of the bad form stuff you guys suggested. Code on.... -T