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

Hello monks, I am trying to finish up a script that will resize a series of images. I have been led to Image::Magick.pm for this task, but I'm having trouble getting everything to fall together.

Here is the code I have:
sub convert_images { my ($array) = (shift); foreach my $picture (@$array) { # read the image via a filehandle my $image = Image::Magick->new; open(IMAGE, "$picture"); $image->Read(file=>\*IMAGE); close(IMAGE); # resize the image to the correct width and height $image->Resize(geometry=>'450X300'); # write the image back to disk $image->Write(filename=>"$picture", compression=>'None'); } }
When I run this it crashes automatically with the error:

Exception 410: no images to mogrify (Resize) Bad file descriptor at picture_html.pl line 233, <STDIN> line 1

Could someone give an explanation on how to fix this or at least point me in the right direction. Thanks in advance. -Eric

Replies are listed 'Best First'.
Re: Image::Magick resize question
by Zaxo (Archbishop) on Jun 08, 2002 at 07:58 UTC

    If you die or warn when failing to open the image, you'll get much better diagnostics. The error message you have suggests that fh IMAGE is not being set to anything useful:

    open IMAGE, "< $picture" or die $!;
    will holler as soon as it sees that your file doesn't open. The message will tell you, more or less, what is lacking. I suspect that either file permissions are wrong, or paths are relative to the wrong directory.

    To live by: Always Check Status of System Interfaces After Use.

    Update: On the error checking and operator precedence issue, you could replace '||' in your $image->Read() statement with &&, but that form is confusing to most people. merlyn's two statement form is more readable to programmers without a strong background. in C.

    After Compline,
    Zaxo

      Yeah, I usually always try to check return values in my code. I actually do catch the return code in my open(image) code like you suggested.

      My actual code is:
      sub convert_images { my ($array, $start_directory) = ($_[0], $_[1]); foreach my $picture (@$array) { # read the image via a filehandle my $image = Image::Magick->new; open(IMAGE, "<$start_directory\\$picture") || die "Unable to o +pen image: $!"; $image->Read(file=>\*IMAGE) || die "Unable to read image: $!"; close(IMAGE); # resize the image to the correct width and height $image->Resize(geometry=>'450X300') || die "Unable to resize i +mage: $!"; # write the image back to disk $image->Write(filename=>"$picture", compression=>'None') || di +e "Unable to write image: $!"; } }
      Even when I run this, the program does not die at the open command. If it did, I'd see my error message "Unable to open image: $!" somewhere in the script error message. That means the file is being opened correctly, right? The line that it complains about is the $image->Resize(geometry='450X300'); line. Am I doing something wrong there? Thanks for the response.
        $image->Read(file=>\*IMAGE) || die "Unable to read image: $!";
        According to my docs, that should be:
        { my $result = $image->Read(file => \*IMAGE); die $result if $result; }
        Perhaps another pass over the manual would be useful, since your code is quite different from anything I've ever seen in the docs. No results are ever returned in $!.

        -- Randal L. Schwartz, Perl hacker

        Just a question on the notation used for the return value for Image::Magick::Read. I understand from merlyn's post that the Read function does not return a result in the error variable ($!).

        Let's just pretend that it did return a value (even though it doesn't). Even then, wouldn't the line

        $image->Read(file=>\*IMAGE) || die "Unable to read image: $!";

        be better written as

        $image->Read(file=>\*IMAGE) or die "Unable to read image: $!";

        The difference being using or instead of ||. Not that it will do anything in this case, but when checking for return values in $!, is one not always suppose to use the "or" operator rather than "||"? I believe I was once told that using "or" (since it has a higher precedence) is always preferred when dealing with this type of situation. Did I hear wrong or am I right? Or does it depend upon the type of function called?

Re: Image::Magick resize question
by emilford (Friar) on Jun 08, 2002 at 06:01 UTC
    First off, could someone explain how I go about editing my posts after I have submitted them. I've noticed people doing it before, but haven't been able to find the way myself. Editing would have been much better than creating this RE: post.

    Second, just to clarify what I am trying to do, I read in a list of image names into an array. I want to resize each of those images to 450X300 before uploading them to a website. I just installed Image::Magick tonight on Win32 and Active State perl. I assume that since I'm getting an Image::Magick related error that I installed it correctly. Plus, it's not complaining about use Image::Magick.