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

Hi guys,

I've been having quite a time with perlmagick .. I just started it, and I have run into trouble on various fronts. Slightly annoyed at that, because I have an OK grasp of Imagemagick itself, so I couldn't understand the lack of progress.

My feeling, then, is that it is my lack of OOPerl knowledge that's causing the problems, as I think perlmagick hinges on that.

I have been over the perlmagick page on the imagemagick site, and it's a little unwieldy (IYDMMSS). Other people seem to have taken this page and copied it wholesale on other sites too.

Is there anywhere else you'd direct me to?

Crucially, it is the montage command that has me all-a-flutter. The main example script actually uses it. And it seems to operate without needing a loop, despite it refers to a variable with several images.

For example, in this extract
$example=$model->Clone(); $example->Label('Wave'); $example->Wave('25x150'); push(@$images,$example); # Create image montage. $montage=$images->Montage(geometry=>'128x160+8+4>',gravity=>'Center', + tile=>'6x+10+200',compose=>'over',background=>'#ffffff', font=>'Generic.ttf',pointsize=>18,fill=>'#600',stroke=>'none');
You can see a push going on, onto the images variable,(itself an image object) and then the montage operation occuring without a loop. It must be some sort of stack that is flattened ... um err.

Sorry for not making myself more clear ... if you only faintly understand, but get a sense of where my problems may lie, a pointer to some illuminating sites would be appreciated.

Many thanks in advance

Replies are listed 'Best First'.
Re: advice on OO and perlmagick
by zentara (Cardinal) on Aug 10, 2008 at 19:41 UTC
    I stumbled upon IM's way of storing multiple images myself, within a single IM object. They get pushed into an array, and when you tell IM to write, it will do all the images it has pushed into it. The only example I have, is a thumbnail creation script, which I have modified to exagerate the IM object's way of processing everything in @$images.

    Notice in this first example, that undef @$image is needed to clear out the image stack. I guess this is a common way of storing data in objects, see "perldoc -q clear", for "how do I clear a package".

    #!/usr/bin/perl use warnings; use strict; use Image::Magick; my $image = Image::Magick->new; umask 0022; my @pics= <*.png>; foreach my $pic (@pics){ my ($picbasename) = $pic =~ /^(.*).png$/; my $ok; $ok = $image->Read($pic) and warn ($ok); my $thumb = $picbasename . '-t.png'; $image->Scale(geometry => '100x100'); $ok = $image->Write($thumb) and warn ($ok); undef @$image; #needed if $image is created outside loop print "$pic -> $thumb\n"; }
    Now in this second example, I don't clear out the data, and tell the IM object to Read multiple files. When I tell the IM object to Write, it will loop thru all it's Read images and write them out, with separate names. I'm sure what montage does, it writes all those images out, put to a single file, NOT multiple files.
    #!/usr/bin/perl use warnings; use strict; use Image::Magick; my $image = Image::Magick->new; umask 0022; my @pics= <*.png>; my $ok; foreach (@pics){ $ok = $image->Read($_) and warn ($ok); } $image->Scale(geometry => '100x100'); $ok = $image->Write('thumb.png') and warn ($ok);
    So here is the second example modified to make a montage, you will see all the files in a single file, instead of auto-named separate files.
    #!/usr/bin/perl use warnings; use strict; use Image::Magick; my $image = Image::Magick->new; umask 0022; my @pics= <*.png>; my $ok; foreach (@pics){ $ok = $image->Read($_) and warn ($ok); } my $montage = $image->Montage(geometry=>'128x160+8+4>',gravity=>'Cente +r', tile=>'6x+10+200',compose=>'over',background=>'#ffffff', font=>'Generic.ttf',pointsize=>18,fill=>'#600',stroke=>'none'); $ok = $montage->Write('montage.png') and warn ($ok);
    So all you need to realize, is that to reuse an IM object, just undef @$images.

    The IM documentation, is particularly confusing and incomplete, sometimes you need to search groups.google.com for examples of syntax, and sometimes you just need to make educated guesses to convert commandline syntax to Perl syntax. The way to get a warning out of an IM object method, is confusing too, I remember getting that tip from merlyn


    I'm not really a human, but I play one on earth Remember How Lucky You Are
Re: advice on OO and perlmagick
by jethro (Monsignor) on Aug 10, 2008 at 20:41 UTC

    In simple terms a perl object is nothing but a pointer to a normal perl data structure with some internal flag that elevates it to an object. (before anyone objects, yes, there is a bit more, especially a connection to a class).

    Most of the time the normal data structure is a hash which doubles as data storage for the object. PerlMagick uses an array as basis of its object. And judging from the documentation, it can either store image data into this array, or recursively other image objects (at least that is my theory, can't test it as Image::Magick wouldn't install when I tried it a minute ago). You can see that in this snippet from an example in the PerlMagick documentation:

    $p = $image->[1]; $p->Draw(stroke=>'red', primitive=>'rectangle', points=>20,20 100,10 +0');

    One of the entries of the object array is taken and on this sub-object the Draw operation is called. To really be sure one would have to print ref($p) to see if it isn't a different object from ref($image), but it seems a neat way to allow the storage and manipulation of more than one image. Now a bit more clarity in the documentation would have been helpful