#example usage: # make_thumbnail_IM('/home/me/i.jpg', '/home/me/i2.jpg', 80, 'square', 90); # will make a 80x80 thumbnail (cropped) quality 90 for picture home/me/i.jpg, and save it to /home/me/i2.jpg sub make_thumbnail_IM{ # receives: # file source (absolute path on machine) # file target out (absolute path on machine) # restriction (pixels) # restriction type # quality my ($src,$out,$restriction,$restrict_type,$quality)=@_; # both restrict to height and width :both won't go over this.. # width restrict to width # height restrict to height # square square - will crop sides or top and bottom to fit. neat. my $img = Image::Magick->new; #blank $img->Read($src); #read source file into blank my ($w,$h) = $img->Get('width','height'); # find dimensions # # # #if width is bigger then height, we use restrict to w if ($restrict_type eq 'both'){ if ($w>$h){ $restrict_type='width'; } else { $restrict_type='height'; } } my $newh; my $neww; # initialize new dimensions # not used if 'square' if ($restrict_type eq 'height') { $neww=(($w*$restriction)/$h); $img->Resize(width=>$neww, height=>$restriction); } if ($restrict_type eq 'width') { $newh=(($h*$restriction)/$w); $img->Resize(width=>$restriction, height=>$newh); } if ($restrict_type eq 'square'){ # my ($cut,$xcut,$ycut); if ($w>$h){ $cut=$h; $xcut=(($w-$h)/2); $ycut=0; } if ($w<$h){ $cut=$w; $xcut=0; $ycut=(($h-$w)/2); } $img->Crop(width=>$cut,height=>$cut,x=>$xcut,y=>$ycut); $img->Resize(width=>$restriction, height=>$restriction); # } $img->Set(quality=>$quality); $img->Write($out); undef $img; } #### #same thing, using GD libary sub make_thumbnail_GD{ # receives: # file source (absolute path on machine) # file target out (absolute path on machine) # restriction # restriction type # quality my ($src,$out,$restriction,$restrict_type,$quality)=@_; # both restrict to height and width :both won't go over this.. # width restrict to width # height restrict to height # square square - will crop sides or top and bottom to fit. neat. my $img = GD::Image->newFromJpeg($src); my ($w,$h) = $img->getBounds(); # find dimensions #if width is bigger then height, we use restrict to w if ($restrict_type eq 'both'){ if ($w>$h){ $restrict_type='width'; } else { $restrict_type='height'; } } my $newh; my $neww; # initialize new dimensions # not used if 'square' if ($restrict_type eq 'height') { $neww=(($w*$restriction)/$h); $newh=$restriction; } if ($restrict_type eq 'width') { $newh=(($h*$restriction)/$w); $neww=$restriction; } if ($restrict_type ne 'square'){ my $newimg = new GD::Image($neww,$newh); $newimg->copyResized($img,0,0,0,0,$neww,$newh,$w,$h); open(FILE, "> $out") || die; print FILE $newimg->jpeg; } else { #square my ($cut,$xcut,$ycut); if ($w>$h){ $cut=$h; $xcut=(($w-$h)/2); $ycut=0; } if ($w<$h){ $cut=$w; $xcut=0; $ycut=(($h-$w)/2); } my $newimg = new GD::Image($restriction,$restriction); $newimg->copyResized($img,0,0,$xcut,$ycut,$restriction,$restriction,$cut,$cut); open(FILE, "> $out") || die; print FILE $newimg->jpeg; } } #### #save it as index.cgi somewhere, chmod 0755 #!/usr/bin/perl use strict; use Cwd; ########################################################## # GD Library #my $il='G'; # comment if you are using ImageMagick instead #use GD; # comment if you are using ImageMagick instead ########################################################## # ImageMagick my $il='I'; # comment if you are using GD library instead use Image::Magick; # comment if using GD Library instead BEGIN { $|=1; use CGI::Carp('fatalsToBrowser'); } =pod INDEXGALLERY Leo Charre for help etc leo@leocharre.com make sure to chmod 0755 Requires: - Image Magick for more info, view readme.txt =cut # MAIN USER DEFINED VARS # #how many to show per page my $perpage=10; # HOW DO YOU WANT THUMBS MADE my $restrict_type='square'; # both restrict to height and width :both won't go over this.. # width restrict to width # height restrict to height # square square - will crop sides or top and bottom to fit. neat. my $restriction=50; #pixels to restrict by. my $quality=85; #quality of thumbnails # if you want to change this later on, you must delete all your .thumbnail files first # DEVEL # # how many thumbs to make per page. Others will say "reload to see thumbnail". By default it is the same # as how many to show per page. This is restricted to 50. my $make=$perpage; # uncomment to custom select how many to make at a time #my $make=10; my $DEBUG_on=0; # set to 1 to see output. # # # ugly hack to keep idiots from blowing up someobody's server if ($make>50) {$make = 50;} # some kind of control. Please no comments :/ # useful for devel my $DEBUG; my $PAGENOW; #present set of img/ my $q=$ENV{'QUERY_STRING'}; #get query string (everything after url? if ($q=~m/p=(\d+)/){ $PAGENOW=$1; #strip any extra shit (could be in archive) } else {$PAGENOW=1;} # accept debug from query string, uncomment to allow if ($q=~m/debug=1/){ $DEBUG_on=1; } my $pwd = cwd; my $docroot= $ENV{'DOCUMENT_ROOT'}; my $d; #where in htdocs, public_html, etc we will work my $d=0; #if we are navigating subdir ??? if ($q=~m/d=([^=&]+)/){ $d=$1; } else { $d = $pwd; $d=~ s/^$docroot//; # (example : now /home/user/web/dir is /dir ) } if ($DEBUG_on) { $DEBUG.=" - d is $d -\n"; } #start subnavigation # this allows navigation back and forth if there are multiple directories # where this script resides (sets), this is in regard to where we are now my $CURRENT_GALLERY_DIRECTORY; #warning, stupid hack follows.. #if this is installed in /stuff/gallery , we don't want to go up a directory.. my $sd=$pwd; #where script is $sd=~s/^.*\///; #take out everything but gallery (in aforementioned case) # now sd contains the name of the dir in which this cript resides, only that, no slashes my $f=$d; $f=~s/^(.*)\/$sd/$sd/; # now we have gallery (or gallery/setthis ) my $prepend=$1; #end stupid hack my @p=split('/',$f); my $path; foreach (@p){ $path.="/$_"; $CURRENT_GALLERY_DIRECTORY.=qq{$_ : }; } #end subnavigation #see what we have here.. # let's look inside and find our images to work with, and or optional sub dirs my @imgs; my @subdirs; opendir(DIR,$docroot.$d); while ($_=readdir(DIR)){ if ($_=~m/\.jpg$|\.jpeg$|\.gif$/i && !($_=~m/^\.thumbnail_/)){ if ($DEBUG_on){ $DEBUG.=" matched $_ --\n"; } push(@imgs,$_); } elsif (-d "$docroot$d/$_" && $_ ne '.' && $_ ne '..') { if ($DEBUG_on){ $DEBUG.=" sub dir found $_ --\n"; } push(@subdirs,$_); } } #create paging if images found my $PAGING; my $imgs_total = 0; $imgs_total=scalar(@imgs); my $control=$imgs_total; my $img_start; my $OUTPUT; #this will contain thumbnails etc. if ($imgs_total){ #if imgs present #paging if ($control>$perpage){ my $p=1; while ( ( $control > 0) ){ $PAGING.=qq{[ Pg $p ] }; $p++; $control=($control - $perpage); } } $img_start=(($PAGENOW*$perpage)-($perpage-1)); #what img to start with if ($DEBUG_on){ $DEBUG.="- imgs_total: $imgs_total
perpage= $perpage
img_start= $img_start
pagenow= $PAGENOW"; } #START OUTPUT my $which= ($img_start-1); my $control=0; #might be one instead until ( $perpage == $control || $which>$imgs_total){ $_=$imgs[$which]; my $name=$_; $name=~s/\.\w+$//;$name=~s/_|-/ /g; if (!-f "$docroot/$d/.thumbnail_$_"){ #check if thumb exists if ($make){ if ($il eq 'GD'){ make_thumbnail_GD("$docroot/$d/$_","$docroot/$d/.thumbnail_$_", $restriction,$restrict_type,$quality); } else { make_thumbnail_IM("$docroot/$d/$_","$docroot/$d/.thumbnail_$_", $restriction,$restrict_type,$quality); } $OUTPUT.=qq{ $name image
$name
$which
}; $make--; } else { $OUTPUT.=qq{ (Reload for Thumb)
$name
$which
}; } } else { $OUTPUT.=qq{ $name image
$name
$which
}; } $which++; $control++; if ($which == $imgs_total ){ last;} } } else { $OUTPUT= q{No images present in this directory.}; } # create sub dir navigation if dirs found my $dirs_total = 0; $dirs_total=scalar(@subdirs); my $SUBNAVIGATION; if ($dirs_total){ #if dirs present $SUBNAVIGATION='Other Sets here:
'; foreach ( @subdirs ){ $SUBNAVIGATION.=qq{[ Set $_ ]
\n }; } if ($DEBUG_on) { $DEBUG.="\n- subdirs_total: $dirs_total\n"; } } #get template, check that css file is there... my $html = &htmlcheck(); #will create if nonexistant, also will get html source - this is so people can edit it. &csscheck(); #will create if nonexistant- so people can edit it. #see if there are includes $html=~s//slurp($docroot.$1)/eg; # make replacements in template read $html=~s/{PAGING}/$PAGING/; $html=~s/{PAGENOW}/$PAGENOW/; $html=~s/{SUBNAVIGATION}/$SUBNAVIGATION/; $html=~s/{OUTPUT}/$OUTPUT/; $html=~s/{CURRENT_GALLERY_DIRECTORY}/$CURRENT_GALLERY_DIRECTORY/; $html=~s/{DEBUG}/$DEBUG/; #obviously if debug was not on, this replaces with nothing. print qq{Content-type: text/html\n\n$html}; exit; sub make_thumbnail_GD{ # receives: # file source (absolute path on machine) # file target out (absolute path on machine) # restriction # restriction type # quality my ($src,$out,$restriction,$restrict_type,$quality)=@_; # both restrict to height and width :both won't go over this.. # width restrict to width # height restrict to height # square square - will crop sides or top and bottom to fit. neat. my $img = GD::Image->newFromJpeg($src); my ($w,$h) = $img->getBounds(); # find dimensions #if width is bigger then height, we use restrict to w if ($restrict_type eq 'both'){ if ($w>$h){ $restrict_type='width'; } else { $restrict_type='height'; } } my $newh; my $neww; # initialize new dimensions # not used if 'square' if ($restrict_type eq 'height') { $neww=(($w*$restriction)/$h); $newh=$restriction; } if ($restrict_type eq 'width') { $newh=(($h*$restriction)/$w); $neww=$restriction; } if ($restrict_type ne 'square'){ my $newimg = new GD::Image($neww,$newh); $newimg->copyResized($img,0,0,0,0,$neww,$newh,$w,$h); open(FILE, "> $out") || die; print FILE $newimg->jpeg; } else { #square my ($cut,$xcut,$ycut); if ($w>$h){ $cut=$h; $xcut=(($w-$h)/2); $ycut=0; } if ($w<$h){ $cut=$w; $xcut=0; $ycut=(($h-$w)/2); } my $newimg = new GD::Image($restriction,$restriction); $newimg->copyResized($img,0,0,$xcut,$ycut,$restriction,$restriction,$cut,$cut); open(FILE, "> $out") || die; print FILE $newimg->jpeg; } } sub make_thumbnail_IM{ # receives: # file source (absolute path on machine) # file target out (absolute path on machine) # restriction # restriction type # quality my ($src,$out,$restriction,$restrict_type,$quality)=@_; # both restrict to height and width :both won't go over this.. # width restrict to width # height restrict to height # square square - will crop sides or top and bottom to fit. neat. my $img = Image::Magick->new; #blank $img->Read($src); #read source file into blank my ($w,$h) = $img->Get('width','height'); # find dimensions # # # #if width is bigger then height, we use restrict to w if ($restrict_type eq 'both'){ if ($w>$h){ $restrict_type='width'; } else { $restrict_type='height'; } } my $newh; my $neww; # initialize new dimensions # not used if 'square' if ($restrict_type eq 'height') { $neww=(($w*$restriction)/$h); $img->Resize(width=>$neww, height=>$restriction); } if ($restrict_type eq 'width') { $newh=(($h*$restriction)/$w); $img->Resize(width=>$restriction, height=>$newh); } if ($restrict_type eq 'square'){ # my ($cut,$xcut,$ycut); if ($w>$h){ $cut=$h; $xcut=(($w-$h)/2); $ycut=0; } if ($w<$h){ $cut=$w; $xcut=0; $ycut=(($h-$w)/2); } $img->Crop(width=>$cut,height=>$cut,x=>$xcut,y=>$ycut); $img->Resize(width=>$restriction, height=>$restriction); # } $img->Set(quality=>$quality); $img->Write($out); undef $img; } sub htmlcheck { my $html=slurp("$pwd/indexgallery_template.html"); unless ($html){ $html=q| IndexGallery

Gallery

{CURRENT_GALLERY_DIRECTORY} Page {PAGENOW}
{PAGING}
{OUTPUT}
{SUBNAVIGATION}
{DEBUG}
|; save ($html, "$pwd/indexgallery_template.html"); } return $html; } sub csscheck { unless (-f "$pwd/indexgallery.css"){ my $css= q|/*this file called indexgallery.css, is created by the file index.cgi if it does not exist. you may edit this file however you want. if you do something to it and it screws up your layout, you can simply delete it. when index.cgi is run again, it will create this file anew for you. for more info on IndexGallery go to http://b3thm00n.com */ /*body */ body { font-family: arial,sans; font-size:11px; color:#666 } /* an item is the outermost div that encases a thumbnail and its info, it is 'one image' */ .item{ margin:4px; float:left; padding:4px; font-size:11px } /* link text appearace */ a:link, a:active, a:visited { color:#a33 } a:hover { color:#f33 } /* paging text */ #paging { font-weight:bold; } #paging a {white-space:nowrap; margin-right:8px; margin-bottom:2px} /* the current path, this is sort of the navigation */ #cdg { font-weight:bold; font-size:13px;} /* other directories in this one.. subdirs.. or 'sets' section*/ #subdirs { font-weight:bold; font-size:11px;} /* the main header text */ h1 { font-size:13px; font-weight:bold } /* The .clear class is applied to a div between the output (the output are the thumbnails in the class="item" divs ) and the footer. If .item class is floated left, and #subdirs is right then this div should clear both */ .clear { clear:both } /* footer */ .footer { font-size:9px; color:#aaa }|; save ($css, "$pwd/indexgallery.css"); } } sub save{ my $src = $_[0]; #the file content my $target = $_[1]; #the file path target if ( open(OUT,"> $target.tmp") ){ print OUT $src; close (OUT); rename("$target.tmp",$target); return 1; } }