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

I've made a photoalbum-type of perl file that displays all the jpg files in a certain folder. It also shows what is a folder and then links to that folder to display further pictures. The perl script displays thumbnails of the pictures; however, I have set the size of the thumbnail to be the same for all. For example, it is set to 192 by 144. When I attempt to change this to a percentange, because different pictures look distored with these deminsions, it messes up the table in which the pictures are being displayed. Perhaps it is the HTML in my script and nothing is wrong with the script, but my main questions is: Is it possible to read a file's demensions through a perl script?

Thanks,
Kyle

Replies are listed 'Best First'.
Re: jpg file demensions
by daddyefsacks (Pilgrim) on Nov 22, 2004 at 20:26 UTC

    Is it possible to read a file's demensions through a perl script?

    Using a module from the CPAN sure, see Image::Size

Re: jpg file demensions
by Zaxo (Archbishop) on Nov 22, 2004 at 20:33 UTC

    Sure, perl -MImage::Size -e'print "$_: @{[imgsize($_)]}\n" for @ARGV' *.jpg or in a script

    use Image::Size; for (glob '*.jpg') { my ($x, $y) = imgsize($_); print "$_: xsize = $x, ysize = $y\n"; }

    After Compline,
    Zaxo

      I am a newbie, and I am not experienced with running libraries (I think that is what they are called), like Image:Size. This sounds like it would do what I want it to. Would someone mind explaining how to implement the library or is there a way that I can accomplish my goal without a library.

      Thanks,
      Kyle

      P.S. - perhaps module is what I mean, and not library.
        The messages above show you how to use a Module in perl code.

        How do you go about getting and installing Modules? Of course there is more than one way to do it ... I highly recommend the Tutorials on Module installation. Here's the gist of it:

        To get modules. First find what you need. http:/seach.cpan.org

        Download the module package and untar.

        Third, follow the instructions in the Readme.txt to install. If you are on a UNIX machine, the installations defaults probably will require that you are root to complete the install. If you are not the System Admin of the UNIX box in question, then the easiest thing to do is to ask the sysadmin to complete the installation for you.

        If you are on a Window box, chances are you have sufficient permissions to do the install.

        Seem complicated? Perhaps, but I garantee that results are worth the effort -- there are thousands of highly functional, highly tested, bits of code on CPAN just waiting for you to use...

        -------------------------------------
        Nothing is too wonderful to be true
        -- Michael Faraday

        Just stumbled upon the following page while traversing the periphery of your similar predicament. You might want to check. Have not tried it yet, though.

        http://www.rdrop.com/~half/General/Downloads/imgdim.pl

        This issue, I just found out, has also been discussed here.

Re: jpg file demensions
by ikegami (Patriarch) on Nov 22, 2004 at 21:51 UTC
    Once you get the dimentions using Image::Magick or whatever, here's code to maintain proportions:
    sub scale_dimentions { my ($width, $height, $max_width, $max_height) = @_; my $width_factor; my $height_factor; my $new_width; my $new_height; my $factor; $width_factor = $max_width / $width; $height_factor = $max_height / $height; if ($width_factor < 1 || $height_factor < 1) { if ($width_factor < $height_factor) { $factor = $width_factor; } else { $factor = $height_factor; } $new_width = int($width * $factor + 0.5); $new_height = int($height * $factor + 0.5); } else { $new_width = $width; $new_height = $height; } return ($new_width, $new_height); } printf("%d,%d$/", scale_dimentions(2272, 1704, 800, 600)); # 800,600 printf("%d,%d$/", scale_dimentions(1704, 2272, 800, 600)); # 450,600 printf("%d,%d$/", scale_dimentions(2272, 1704, 150, 150)); # 150,112 printf("%d,%d$/", scale_dimentions(1704, 2272, 150, 150)); # 112,150
      If I am running a website off of another server, where I do not have access to install new modules, how would I go about do such?

      Thanks
        You could request the service provider to install the module for you (maybe change providers if they won't), or you could get the Image::Size module from CPAN, look at the subroutine "jpegsize", and adapt that code into a subroutine for your script (giving proper credit to the module author of course).
Re: jpg file demensions
by Roy Johnson (Monsignor) on Nov 22, 2004 at 20:29 UTC
    You might want to use the Image::Magick module to get the dimensions, and even to resize them.

    Caution: Contents may have been coded under pressure.
Re: jpg file demensions
by zentara (Cardinal) on Nov 23, 2004 at 14:21 UTC
    Just to maybe give you some ideas on how to do this, here are a few scripts I wrote to display thumbnails and images. Just run the script in a directory of jpgs and load the index.html it creates.

    I found you can do it easily either with Image::Magick or Imager. They will handle the resizing a bit differently. So you might want to check out the differences between Imager and Image::Magick. In 1 scenario, you need to decide if you want to have a constant width or height for the thumbnails; in the other scenario, you reduce them by a percentage, but you must save the new thumbnail dimensions so the html display won't get distorted.

    With Image::Magick

    #!/usr/bin/perl use warnings; use strict; use Image::Magick; use Cwd; #watch the width of your picture names #they can widen the table cells if too long umask 0022; my $image = Image::Magick->new; my $count = 0; my $dir = cwd; open(HEADER,">header.html"); print HEADER<<End_Header; <html> <BODY Text="#99CCFF" BGCOLOR="#000000"> <center><h1>Thumbnails for $dir</h1></center> </body> </html> End_Header close HEADER; open(INDEX,">index.html"); print INDEX<<End_Index; <html> <head> <TITLE>Thumbnails</TITLE> <link rel="icon" href="favicon.ico"> </head> <frameset rows="70,*" border="0"> <frame name="header" src="header.html" marginwidth="0" marginheight=" +0" scrolling="off" frameborder="0"> <frameset cols="130,*" border="0"> <frame name="left" src="left.html" marginwidth="5" marginheight="5 +" scrolling="yes" frameborder="5"> <frame name="main" src="main.html" marginwidth="5" marginheight="5 +" scrolling="yes" frameborder="5"> </frameset> </frameset> </html> End_Index close INDEX; open(MAIN,">main.html"); print MAIN<<End_Main; <html> <BODY TEXT="#FFCCCC" BGCOLOR="#000000"> <center><h1>Click thumbnails at left to view</h1></center> </body> </html> End_Main close MAIN; open(OUT,">left.html"); print OUT<<End_Header; <html> <body> <table align=left bgcolor=9999CC border=2 cellpadding=2 cellspacing=2> <tr> End_Header my @pics= <*.jpg>; foreach my $pic (@pics){ $count++; my ($picbasename) = $pic =~ /^(.*).jpg$/; my $ok; $ok = $image->Read($pic) and warn ($ok); my ($w,$h)= $image->Get('columns','height'); my $thumb = $picbasename . '-t.jpg'; $ok = $image->Scale(geometry => '100x100')and warn ($ok); $ok = $image->Write($thumb)and warn ($ok); my ($tw,$th)= $image->Get('columns','height'); my $picoptions= $w.'x'.$h.'x'.$tw.'x'.$th; print "$pic\t$picoptions\n"; undef @$image; print OUT<<EOTR; <td align=center><a href="$pic" target=main HEIGHT=$h WIDTH=$w alt="[ +$pic]"><img alt= [$pic-thumbnail] src=$thumb height=$th width=$tw></a +><br>$pic</td> EOTR if($count == 1){print OUT "</tr><tr>"; $count = 0}; } print OUT<<EOHTML; </tr> </table> </body> </html> EOHTML close OUT; __END__

    With Imager #########################################

    #!/usr/bin/perl use warnings; use strict; use Imager; use Cwd; use File::Basename; #but imager makes it easy opening different file types #watch the width of your picture names #they can widen the table cells if too long umask 0022; my $image = Imager->new(); my $count = 0; my $dir = cwd; my @exts = qw(.jpg .png .gif); # list allowed extensions my @pics= <*.jpg *.gif *.png>; open(HEADER,">header.html"); print HEADER<<End_Header; <html> <BODY Text="#99CCFF" BGCOLOR="#000000"> <center><h1>Thumbnails for $dir</h1></center> </body> </html> End_Header close HEADER; open(INDEX,">index.html"); print INDEX<<End_Index; <html> <head> <TITLE>Thumbnails</TITLE> <link rel="icon" href="favicon.ico"> </head> <frameset rows="70,*" border="0"> <frame name="header" src="header.html" marginwidth="0" marginheight=" +0" scrolling="off" frameborder="0"> <frameset cols="130,*" border="0"> <frame name="left" src="left.html" marginwidth="5" marginheight="5 +" scrolling="yes" frameborder="5"> <frame name="main" src="main.html" marginwidth="5" marginheight="5 +" scrolling="yes" frameborder="5"> </frameset> </frameset> </html> End_Index close INDEX; open(MAIN,">main.html"); print MAIN<<End_Main; <html> <BODY TEXT="#FFCCCC" BGCOLOR="#000000"> <center><h1>Click thumbnails at left to view</h1></center> </body> </html> End_Main close MAIN; open(OUT,">left.html"); print OUT<<End_Header; <html> <body> <table align=left bgcolor=9999CC border=2 cellpadding=2 cellspacing=2> <tr> End_Header foreach my $pic (@pics){ $count++; my ($basename,$path,$suffix) = fileparse($pic,@exts); $image->open(file=>$pic) or die $image->errstr(); # my $w = $image->getwidth(); # my $h = $image->getheight(); # Create smaller version my $thumb = $image->scale(xpixels=>100); #$basename.="-t$suffix"; #keeps same ext $basename.='-t.jpg'; #make all thumbs as jpg print "Storing image as: $basename\n"; $thumb->write(file=>$basename, jpegquality=>30) or die $thumb->e +rrstr; # my $tw = $thumb->getwidth(); # my $th = $thumb->getheight(); print OUT<<EOTR; <td align=center><a href="$pic" target=main alt="[$pic]"><img alt= [$p +ic-thumbnail] src=$basename ></a><br>$pic</td> EOTR if($count == 1){print OUT "</tr><tr>"; $count = 0}; } print OUT<<EOHTML; </tr> </table> </body> </html> EOHTML close OUT; __END__

    I'm not really a human, but I play one on earth. flash japh
Re: jpg file demensions
by TedPride (Priest) on Nov 23, 2004 at 04:26 UTC
    Can't you unpack the module on your own computer and then FTP it to the cgi-bin directory? Do you need root access to install a module? I'm kind of curious about this myself, since I've never installed a module except on my own computer.

      You don't need root access to install a module. You simply need to save it into a specific location such as /usr/local/path/to/MyModules/ModName.pm. Then include the module in your code using the lib pragma, like so:

      #!/usr/bin/perl -w use strict; use lib "/usr/local/path/to"; # Notice where this path ends... :) use MyModules::ModName; # Other use statements... # ...on with other code...

      This should work as long as the module is packaged into 'MyModules::ModName'. If it's a pre-existing module you're working with, alter the path in the lib statement and name in the use statement, accordingly. :)

      At least that's the way I've done it. If this is incorrect, I'm certain someone will correct me. I'd even go so far as to appreciate it! :)

      Hope this helps,

      /Larry