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

I was told "If you append [0] to a filename it will always return the first frame of a multi-frame image (e.g. image.gif[0])."

I'm using a CGI upload form and it works if it's not a multi-frame image. If it is, I get a million thumbnails I don't want. I tried this suggestion but now NO thumbnails are created whatsoever. Can someone point out where I made my OOPSIE?

my $remotefile = param("image"); # make new variable to prevent overwriting my $filename = $remotefile; # remove all the junk in our filename $filename =~ s/^.*[\\\/]//; #begin image magic my ($image, $x); $image=Image::Magick->new; $x = $image->Read($localfile); warn "$x" if "$x"; $x = $image->Resize(width=>500, height=>500); $localfile = $filename; $localfile =~ /(.*)\.(.*)/; $newfilename = "$1.png"; $x = $image->Write($newfilename); warn "$x" if "$x";

Replies are listed 'Best First'.
Re: Saving the first frame of any image
by gt8073a (Hermit) on Mar 25, 2004 at 18:00 UTC
    $x = $image->Read($localfile);
    You are not reading any data in.
    The following is a partial listing from some code I use often enough. Look for ## <-- LOOK AT ME below to see how to only get a single image.
    Note: this code is not tested per se, it is ripped from working code. But it should get you on the right path.
    my $remotefile = param("image"); ## you need to read in the data from the uploaded file my $data; { local $/; $data = <$remotefile>; } ## directory is defined above ## name is defined above, dependings on what sort of naming convention + you want ## magick is defined above my $saveFile = "${directory}${$name}.${magick}"; #begin image magick my ($image, $x); $image=Image::Magick->new or die( 'my error message' ); $image->BlobToImage($data); ## read uploaded data into IM ## kill layers/pages/etc $image = $image->[0]; ## <-- LOOK AT ME $image->Flatten(); ## i don't know why art directors hate uploadin +g flattened images, but they do.. #$x = $image->Resize(width=>500, height=>500); ## scale the image if I need to ## hardcoded 500s! my ( $hRatio, $wRatio ) = ( 500 / $image->Get( 'rows' ), 500 / $image- +>Get( 'columns' ) ); unless ( $hRatio > 1 and $wRatio > 1 ) { ## + image is smaller than limits my $multiplier = $hRatio < $wRatio ? $hRatio : $wRatio ; $image->Scale( height => int( $image->Get('rows') * $multi +plier ), width => int( $image->Get('columns') * $multi +plier ) ); } ## explicitly set the magick $image->Set( 'magick' => $magick ); $x = $image->Write( $saveFile ); warn "$x" if "$x";

    Will perl for money
    JJ Knitis

      Thanks for your code! I tried making the changes needed but now I get an error rather than it just not working. This script uploads the image as a whole then it creates and uploads the thumbnail of it. I only want the first frame of the thumbnail uploaded, the rest can rott in the cyber morgue.

      This entire script worked a few days ago, it uploaded the image and the thumbnails..but I tried to make it to only upload one thumbnail and I killed the script! lol.

      Error:

      rock6.jpg Software error: Can't call method "Flatten" on an undefined value at uploadv25.pl line + 232.
      I did a test print on $filename and you can see it prints out successfully before the script dies. So how can it say it's undefined?
      print $filename; $localfile = $filename; $localfile =~ m/(.*)\.(.*)/; $newfilename = "$thumbdir/$1.png"; my ($image, $x); $image=Image::Magick->new; $image->BlobToImage($localfile); $image = $image->[0]; $image->Flatten(); #$x = $image->Read($localfile); warn "$image" if "$image"; $x = $image->Resize(width=>100, height=>100); $x = $image->Write($newfilename); warn "$x" if "$x";
      The following preceeds the rest of the code above, this is what I'm using to upload the entire image itself to the server before ImageMagick is used. Remember, this DOES work and files DO upload.
      open( SAVED, ">>$localfile" ); # || die $!; while ( $bytesread = read( $remotefile, $buffer, 1024 ) ) { print SAVED $buffer; } close SAVED;
      Thanks for your help!
        $image->BlobToImage($localfile) isn't right. As gt8073a put in his comments, "## you need to read in the data from the uploaded file." He used <> and you used ->Read() originally.

        -- 
        LP^>

Re: Saving the first frame of any image
by PodMaster (Abbot) on Mar 26, 2004 at 07:56 UTC
    # remove all the junk in our filename $filename =~ s/^.*[\\\/]//;
    Does not remove all the junk in your filename (you should be using taint, perldoc perlsec). This still has potential for abuse. Adding something like
    $filename = pack 'H*', $filename;
    after that substitution ought to remedy that.

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.