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

I have a few ImageMagick questions I was wondering if someone could help me with.

Let's say I have a box, and inside this box I have another box.

################## # # # ############ # # # # # # # # # # ############ # # # ##################
I have a gray outerbox and a white innerbox as my image.jpg. I want to write text using ImageMagick in this white are and no where else. I already know how to write text ontop of an image, but how can I make it so the text I want will always be in this white area and in the case it's too big, the text will split into separate lines so it fits?

In short, my question is.. Is it possible to set coordinates for text wrapping so the text won't ever leave a specific area? I will be using an array to print text so it's not like it will always be one string, it'll be different sizes and I want to be able to text wrap and center it inside these coordinates.

Replies are listed 'Best First'.
Re: random ImageMagick questions
by valdez (Monsignor) on Mar 23, 2004 at 17:24 UTC

    Sorry, Image::Magick hasn't what you are looking for; you can of course build your own system using QueryFontMetrics; here is an example of its usage:

    #!/usr/bin/perl use Image::Magick; $i = Image::Magick->new; $i->Set( size => '320x200' ); $i->ReadImage('xc:white'); @params = ( font => '@arial.ttf', text => 'some text', pointsize => 36 ); ($w, $h, $ascend, $descend, $text_w, $text_h, $max) = $i->QueryFontMetrics( @params ); print "$w, $h, $ascend, $descend, $text_w, $text_h, $max\n"; $i->Annotate( @params, stroke => red, fill => red, gravity => center ); $i->Display;

    HTH, Valerio

Re: random ImageMagick questions
by matija (Priest) on Mar 23, 2004 at 08:22 UTC
    First, I assume that you know the actual dimensions of the white box - determining it's dimensions if you're given the picture, is a separate problem.

    Second, going through Image::Magick's documentation, their support of text if not very advanced. Perhaps you'd find it easier to use GD::Text. Not only does it support TrueType fonts, but the width method will return the width of text in pixels - which is exactly what you need to determine where to wrap your string.

Re: random ImageMagick questions
by halley (Prior) on Mar 23, 2004 at 13:58 UTC

    If you want to clip the text to a given area, you may want to (1) create a new separate image of just the writable area, write your text in that, then apply it to the larger image, or (2) draw the text before you draw the other elements, so that the other elements overwrite any stray parts of the text.

    Determining the extent (the bounding box) of the written text (before or after drawing) can be tricky, but I think Perl::Magick offers some routines to determine that.

    Deciding how to alter your text to fit within a given space is far more tricky, and is usually an iterative process that is almost like trial and error. You have to decide what can be altered: font size, word wrapping, word breaking, etc. There will always be some strings that just can't fit: supercalifragilisticexpialidocious won't fit in a 128x128 icon and remain legible.

    --
    [ e d @ h a l l e y . c c ]

Re: random ImageMagick questions
by zentara (Cardinal) on Mar 23, 2004 at 16:12 UTC
    This was posted by an honorable monk some time ago:
    !/usr/bin/perl use strict; use warnings; use Image::Magick; my $label = Image::Magick->new( size => "600x600", ); $label->Read("xc:white"); $label->Draw( primitive => 'line', points => "300,100 300,500", stroke => '#600', ); $label->Draw( primitive => 'line', points => "100,300 500,300", stroke => '#600', ); $label->Draw( primitive => 'rectangle', points => "100,100 500,500", fill => 'none', stroke => '#600', ); my $x = $label->Annotate( text => "North West", 'x' => 150, 'y' => 150, pointsize => 40, # font => $ENV{WINDIR}.'\Fonts\Tahomabd.ttf', font => 'arial.ttf' ); die "$x" if "$x"; $label->Write("$0.png");

    I'm not really a human, but I play one on earth. flash japh