#!/usr/bin/perl
# resize.pl - (C) James Richardson 2001-2007
# Licensed under the GPL v2 or your choice of a later version.
# If you use this / find it helpful please send me an email to let me know.
use HTTP::Daemon;
use HTTP::Response;
use HTTP::Headers;
use Image::Magick;
use FileHandle;
use Data::Dumper;
use strict;
my $FILTER = "Cubic";
my $BLUR = 0.125;
$SIG{CHLD} = sub {
my $pid = wait;
print "Child $pid exited\n";
};
sub Log {
print join(":", @_ );
print "\n";
}
sub Info { Log ( "Info", @_ ); }
sub ratio {
my ( $image ) = @_;
my $currentx = $image->Get("width");
my $currenty = $image->Get("height");
my $ratio = $currenty / $currentx;
Info ("Current file is $currentx x $currenty, Ratio = $ratio");
return $ratio;
}
sub resize_without_crop {
my ($image, $wantedx, $wantedy) = @_;
my $ratio = ratio($image);
if ( $wantedx && $wantedy ) {
}
elsif ( $wantedx ) {
$wantedy = $wantedx * $ratio;
}
elsif ( $wantedy ) {
$wantedx = $wantedy / $ratio;
}
$image->Resize(filter=>$FILTER, blur=>$BLUR, width=>$wantedx, height=>$wantedy);
}
sub resize_with_crop {
my ( $image, $wantedx, $wantedy ) = @_;
if ( ! ( $wantedx && $wantedy )) {
die "Need both x and y sizes for cropping";
}
my $ratio = ratio($image);
if ( $ratio >= 1 ) {
# Portrait (or square) Image
# Resize using the given width and then crop to the height
resize_without_crop($image, $wantedx, undef);
}
else {
# Landscape Image
resize_without_crop($image, undef, $wantedy);
}
$image->Crop(width=>$wantedx, height=>$wantedy, x=>0, y=>0);
}
sub resize {
my ( $filename, $filetype, $wantedx, $wantedy, $allowcrop, $tobw, $dull ) = @_;
my $quality = 95;
my $image = Image::Magick->new();
$image->Read(filename=>$filename);
if ( $allowcrop ) {
resize_with_crop($image, $wantedx, $wantedy);
}
else {
resize_without_crop($image, $wantedx, $wantedy);
}
if ( $tobw ) {
Info("Converting to B/W");
$image->Set(colorspace=>"gray");
$image->Quantize();
}
if ( $dull ) {
for ( my $i = 0 ; $i < $dull ; $i++ ) {
Info("Dulling");
$image->Contrast(sharpen=>"False");
}
}
my $outputx = $image->Get("width");
my $outputy = $image->Get("height");
$image->Set(quality=>$quality);
Info ( "Returned image is: Width = $outputx, Height = $outputy, Format = $filetype" );
my @bytes = $image->ImageToBlob(magick=>$filetype);
my $buffer = $bytes[0];
return $outputx, $outputy, $buffer;
}
#################################################################
#
# Main Program
#
#################################################################
my $listenport = 5300;
my $daemon = HTTP::Daemon->new ( LocalPort => $listenport, Reuse=>1 );
if ( !defined ( $daemon ) ) {
Info ( "Can't listen on listenport $listenport: $!" );
exit;
}
Info ( "Listening on port $listenport" );
while ( 1 ) {
while ( my $client = $daemon->accept() ) {
my $pid = fork();
if ( $pid == 0 ) {
# This is the client
my $request = $client->get_request();
my $uri = $request->uri();
my %q = $uri->query_form();
my $file = $q{file};
my $x = $q{x};
my $y = $q{y};
my $filetype = $q{filetype};
my $crop = exists $q{crop} ? 1 : 0;
my $bw = exists $q{bw} ? 1 : 0;
my $dull = $q{dull};
Info ( "File is $file, $filetype, X=$x,Y=$y, Crop=$crop, B/W=$bw" );
my ( $width, $height, $image ) = resize ( $file, $filetype, $x, $y, $crop, $bw, $dull );
if ( defined ( $image ) ) {
my $header = new HTTP::Headers ( "Content-Type" => "image/jpeg",
"X-Image-Width" => $width,
"X-Image-Height" => $height );
$client->send_response ( new HTTP::Response ( 200, "OK", $header, $image ) );
exit;
}
}
elsif ( $pid > 0 ) {
# This is the parent
}
else {
print "fork() failed $!\n";
}
}
}