Move icon resizing code to the LJ::Userpic package.
Patch by kareila.
diffs (434 lines):
diff -r 62e8e4716e81 -r b29d6cfc5a83 bin/worker/userpic-resize-gm
--- a/bin/worker/userpic-resize-gm Wed Sep 08 14:21:07 2010 +0800
+++ b/bin/worker/userpic-resize-gm Wed Sep 08 14:41:32 2010 +0800
@@ -26,6 +26,6 @@ sub lj_upf_resize {
sub lj_upf_resize {
my $job = shift;
my $args = eval { Storable::thaw($job->arg) } || [];
- return Storable::nfreeze(LJ::_get_upf_scaled(@$args));
+ return Storable::nfreeze( LJ::Userpic->_get_upf_scaled( @$args ) );
}
diff -r 62e8e4716e81 -r b29d6cfc5a83 cgi-bin/LJ/Userpic.pm
--- a/cgi-bin/LJ/Userpic.pm Wed Sep 08 14:21:07 2010 +0800
+++ b/cgi-bin/LJ/Userpic.pm Wed Sep 08 14:41:32 2010 +0800
@@ -711,6 +711,184 @@ sub create {
return $upic;
}
+# this will return a user's userpicfactory image stored in mogile scaled down.
+# if only $size is passed, will return image scaled so the largest dimension
will
+# not be greater than $size. If $x1, $y1... are set then it will return the
image
+# scaled so the largest dimension will not be greater than 100
+# all parameters are optional, default size is 640.
+#
+# if maxfilesize option is passed, get_upf_scaled will decrease the image
quality
+# until it reaches maxfilesize, in kilobytes. (only applies to the 100x100
userpic)
+#
+# returns [imageref, mime, width, height] on success, undef on failure.
+#
+# note: this will always keep the image's original aspect ratio and not
distort it.
+sub get_upf_scaled {
+ my ( $class, @args ) = @_;
+
+ my $gc = LJ::gearman_client();
+
+ # no gearman, do this in-process
+ return $class->_get_upf_scaled( @args ) unless $gc;
+
+ # invoke gearman
+ my $u = LJ::get_remote() or die "No remote user";
+ unshift @args, "userid" => $u->id;
+
+ my $result;
+ my $arg = Storable::nfreeze(\...@args);
+ my $task = Gearman::Task->new('lj_upf_resize', \$arg,
+ {
+ uniq => '-',
+ on_complete => sub {
+ my $res = shift;
+ return unless $res;
+ $result = Storable::thaw($$res);
+ }
+ });
+
+ my $ts = $gc->new_task_set();
+ $ts->add_task($task);
+ $ts->wait(timeout => 30); # 30 sec timeout;
+
+ # job failed ... error reporting?
+ die "Could not resize image down\n" unless $result;
+
+ return $result;
+}
+
+# actual method
+sub _get_upf_scaled
+{
+ my ( $class, %opts ) = @_;
+ my $size = delete $opts{size} || 640;
+ my $x1 = delete $opts{x1};
+ my $y1 = delete $opts{y1};
+ my $x2 = delete $opts{x2};
+ my $y2 = delete $opts{y2};
+ my $border = delete $opts{border} || 0;
+ my $maxfilesize = delete $opts{maxfilesize} || 38;
+ my $u = LJ::want_user(delete $opts{userid} || delete $opts{u}) ||
LJ::get_remote();
+ my $mogkey = delete $opts{mogkey};
+ my $downsize_only = delete $opts{downsize_only};
+ croak "No userid or remote" unless $u || $mogkey;
+
+ $maxfilesize *= 1024;
+
+ croak "Invalid parameters to get_upf_scaled\n" if scalar keys %opts;
+
+ my $mode = ($x1 || $y1 || $x2 || $y2) ? "crop" : "scale";
+
+ eval "use Image::Magick (); 1;"
+ or return undef;
+
+ eval "use Image::Size (); 1;"
+ or return undef;
+
+ $mogkey ||= 'upf:' . $u->{userid};
+ my $dataref = LJ::mogclient()->get_file_data($mogkey) or return undef;
+
+ # original width/height
+ my ($ow, $oh) = Image::Size::imgsize($dataref);
+ return undef unless $ow && $oh;
+
+ # converts an ImageMagick object to the form returned to our callers
+ my $imageParams = sub {
+ my $im = shift;
+ my $blob = $im->ImageToBlob;
+ return [\$blob, $im->Get('MIME'), $im->Get('width'),
$im->Get('height')];
+ };
+
+ # compute new width and height while keeping aspect ratio
+ my $getSizedCoords = sub {
+ my $newsize = shift;
+
+ my $fromw = $ow;
+ my $fromh = $oh;
+
+ my $img = shift;
+ if ($img) {
+ $fromw = $img->Get('width');
+ $fromh = $img->Get('height');
+ }
+
+ return (int($newsize * $fromw/$fromh), $newsize) if $fromh > $fromw;
+ return ($newsize, int($newsize * $fromh/$fromw));
+ };
+
+ # get the "medium sized" width/height. this is the size which
+ # the user selects from
+ my ($medw, $medh) = $getSizedCoords->($size);
+ return undef unless $medw && $medh;
+
+ # simple scaling mode
+ if ($mode eq "scale") {
+ my $image = Image::Magick->new(size => "${medw}x${medh}")
+ or return undef;
+ $image->BlobToImage($$dataref);
+ unless ($downsize_only && ($medw > $ow || $medh > $oh)) {
+ $image->Resize(width => $medw, height => $medh);
+ }
+ return $imageParams->($image);
+ }
+
+ # else, we're in 100x100 cropping mode
+
+ # scale user coordinates up from the medium pixelspace to full pixelspace
+ $x1 *= ($ow/$medw);
+ $x2 *= ($ow/$medw);
+ $y1 *= ($oh/$medh);
+ $y2 *= ($oh/$medh);
+
+ # cropping dimensions from the full pixelspace
+ my $tw = $x2 - $x1;
+ my $th = $y2 - $y1;
+
+ # but if their selected region in full pixelspace is 800x800 or something
+ # ridiculous, no point decoding the JPEG to its full size... we can
+ # decode to a smaller size so we get 100px when we crop
+ my $min_dim = $tw < $th ? $tw : $th;
+ my ($decodew, $decodeh) = ($ow, $oh);
+ my $wanted_size = 100;
+ if ($min_dim > $wanted_size) {
+ # then let's not decode the full JPEG down from its huge size
+ my $de_scale = $wanted_size / $min_dim;
+ $decodew = int($de_scale * $decodew);
+ $decodeh = int($de_scale * $decodeh);
+ $_ *= $de_scale foreach ($x1, $x2, $y1, $y2);
+ }
+
+ $_ = int($_) foreach ($x1, $x2, $y1, $y2, $tw, $th);
+
+ # make the pristine (uncompressed) 100x100 image
+ my $timage = Image::Magick->new(size => "${decodew}x${decodeh}")
+ or return undef;
+ $timage->BlobToImage($$dataref);
+ $timage->Scale(width => $decodew, height => $decodeh);
+
+ my $w = ($x2 - $x1);
+ my $h = ($y2 - $y1);
+ my $foo = $timage->Mogrify(crop => "${w}x${h}+$x1+$y1");
+
+ my $targetSize = $border ? 98 : 100;
+
+ my ($nw, $nh) = $getSizedCoords->($targetSize, $timage);
+ $timage->Scale(width => $nw, height => $nh);
+
+ # add border if desired
+ $timage->Border(geometry => "1x1", color => 'black') if $border;
+
+ foreach my $qual (qw(100 90 85 75)) {
+ # work off a copy of the image so we aren't recompressing it
+ my $piccopy = $timage->Clone();
+ $piccopy->Set('quality' => $qual);
+ my $ret = $imageParams->($piccopy);
+ return $ret if length(${ $ret->[0] }) < $maxfilesize;
+ }
+
+ return undef;
+}
+
# make this picture the default
sub make_default {
my $self = shift;
diff -r 62e8e4716e81 -r b29d6cfc5a83 cgi-bin/ljuserpics.pl
--- a/cgi-bin/ljuserpics.pl Wed Sep 08 14:21:07 2010 +0800
+++ b/cgi-bin/ljuserpics.pl Wed Sep 08 14:41:32 2010 +0800
@@ -354,186 +354,5 @@ sub get_picid_from_keyword
return $default;
}
-# this will return a user's userpicfactory image stored in mogile scaled down.
-# if only $size is passed, will return image scaled so the largest dimension
will
-# not be greater than $size. If $x1, $y1... are set then it will return the
image
-# scaled so the largest dimension will not be greater than 100
-# all parameters are optional, default size is 640.
-#
-# if maxfilesize option is passed, get_upf_scaled will decrease the image
quality
-# until it reaches maxfilesize, in kilobytes. (only applies to the 100x100
userpic)
-#
-# returns [imageref, mime, width, height] on success, undef on failure.
-#
-# note: this will always keep the image's original aspect ratio and not
distort it.
-sub get_upf_scaled {
- my @args = @_;
-
- my $gc = LJ::gearman_client();
-
- # no gearman, do this in-process
- return LJ::_get_upf_scaled(@args)
- unless $gc;
-
- # invoke gearman
- my $u = LJ::get_remote()
- or die "No remote user";
- unshift @args, "userid" => $u->id;
-
- my $result;
- my $arg = Storable::nfreeze(\...@args);
- my $task = Gearman::Task->new('lj_upf_resize', \$arg,
- {
- uniq => '-',
- on_complete => sub {
- my $res = shift;
- return unless $res;
- $result = Storable::thaw($$res);
- }
- });
-
- my $ts = $gc->new_task_set();
- $ts->add_task($task);
- $ts->wait(timeout => 30); # 30 sec timeout;
-
- # job failed ... error reporting?
- die "Could not resize image down\n" unless $result;
-
- return $result;
-}
-
-# actual method
-sub _get_upf_scaled
-{
- my %opts = @_;
- my $size = delete $opts{size} || 640;
- my $x1 = delete $opts{x1};
- my $y1 = delete $opts{y1};
- my $x2 = delete $opts{x2};
- my $y2 = delete $opts{y2};
- my $border = delete $opts{border} || 0;
- my $maxfilesize = delete $opts{maxfilesize} || 38;
- my $u = LJ::want_user(delete $opts{userid} || delete $opts{u}) ||
LJ::get_remote();
- my $mogkey = delete $opts{mogkey};
- my $downsize_only = delete $opts{downsize_only};
- croak "No userid or remote" unless $u || $mogkey;
-
- $maxfilesize *= 1024;
-
- croak "Invalid parameters to get_upf_scaled\n" if scalar keys %opts;
-
- my $mode = ($x1 || $y1 || $x2 || $y2) ? "crop" : "scale";
-
- eval "use Image::Magick (); 1;"
- or return undef;
-
- eval "use Image::Size (); 1;"
- or return undef;
-
- $mogkey ||= 'upf:' . $u->{userid};
- my $dataref = LJ::mogclient()->get_file_data($mogkey) or return undef;
-
- # original width/height
- my ($ow, $oh) = Image::Size::imgsize($dataref);
- return undef unless $ow && $oh;
-
- # converts an ImageMagick object to the form returned to our callers
- my $imageParams = sub {
- my $im = shift;
- my $blob = $im->ImageToBlob;
- return [\$blob, $im->Get('MIME'), $im->Get('width'),
$im->Get('height')];
- };
-
- # compute new width and height while keeping aspect ratio
- my $getSizedCoords = sub {
- my $newsize = shift;
-
- my $fromw = $ow;
- my $fromh = $oh;
-
- my $img = shift;
- if ($img) {
- $fromw = $img->Get('width');
- $fromh = $img->Get('height');
- }
-
- return (int($newsize * $fromw/$fromh), $newsize) if $fromh > $fromw;
- return ($newsize, int($newsize * $fromh/$fromw));
- };
-
- # get the "medium sized" width/height. this is the size which
- # the user selects from
- my ($medw, $medh) = $getSizedCoords->($size);
- return undef unless $medw && $medh;
-
- # simple scaling mode
- if ($mode eq "scale") {
- my $image = Image::Magick->new(size => "${medw}x${medh}")
- or return undef;
- $image->BlobToImage($$dataref);
- unless ($downsize_only && ($medw > $ow || $medh > $oh)) {
- $image->Resize(width => $medw, height => $medh);
- }
- return $imageParams->($image);
- }
-
- # else, we're in 100x100 cropping mode
-
- # scale user coordinates up from the medium pixelspace to full pixelspace
- $x1 *= ($ow/$medw);
- $x2 *= ($ow/$medw);
- $y1 *= ($oh/$medh);
- $y2 *= ($oh/$medh);
-
- # cropping dimensions from the full pixelspace
- my $tw = $x2 - $x1;
- my $th = $y2 - $y1;
-
- # but if their selected region in full pixelspace is 800x800 or something
- # ridiculous, no point decoding the JPEG to its full size... we can
- # decode to a smaller size so we get 100px when we crop
- my $min_dim = $tw < $th ? $tw : $th;
- my ($decodew, $decodeh) = ($ow, $oh);
- my $wanted_size = 100;
- if ($min_dim > $wanted_size) {
- # then let's not decode the full JPEG down from its huge size
- my $de_scale = $wanted_size / $min_dim;
- $decodew = int($de_scale * $decodew);
- $decodeh = int($de_scale * $decodeh);
- $_ *= $de_scale foreach ($x1, $x2, $y1, $y2);
- }
-
- $_ = int($_) foreach ($x1, $x2, $y1, $y2, $tw, $th);
-
- # make the pristine (uncompressed) 100x100 image
- my $timage = Image::Magick->new(size => "${decodew}x${decodeh}")
- or return undef;
- $timage->BlobToImage($$dataref);
- $timage->Scale(width => $decodew, height => $decodeh);
-
- my $w = ($x2 - $x1);
- my $h = ($y2 - $y1);
- my $foo = $timage->Mogrify(crop => "${w}x${h}+$x1+$y1");
-
- my $targetSize = $border ? 98 : 100;
-
- my ($nw, $nh) = $getSizedCoords->($targetSize, $timage);
- $timage->Scale(width => $nw, height => $nh);
-
- # add border if desired
- $timage->Border(geometry => "1x1", color => 'black') if $border;
-
- foreach my $qual (qw(100 90 85 75)) {
- # work off a copy of the image so we aren't recompressing it
- my $piccopy = $timage->Clone();
- $piccopy->Set('quality' => $qual);
- my $ret = $imageParams->($piccopy);
- return $ret if length(${ $ret->[0] }) < $maxfilesize;
- }
-
- return undef;
-}
-
-
1;
diff -r 62e8e4716e81 -r b29d6cfc5a83 htdocs/editicons.bml
--- a/htdocs/editicons.bml Wed Sep 08 14:21:07 2010 +0800
+++ b/htdocs/editicons.bml Wed Sep 08 14:41:32 2010 +0800
@@ -200,7 +200,7 @@ use strict;
return $err->("Invalid userpic creation parameters.") if
(!$scaledsizemax || !$x2);
my $picinfo = eval {
- LJ::get_upf_scaled(
+ LJ::Userpic->get_upf_scaled(
x1 => $x1,
y1 => $y1,
x2 => $x2,
@@ -802,7 +802,7 @@ sub parse_post_uploads
}
eval {
- my $picinfo = LJ::get_upf_scaled(
+ my $picinfo = LJ::Userpic->get_upf_scaled(
size => 100,
u => $u,
mogkey => "upf_${counter}:$u->{userid}"
diff -r 62e8e4716e81 -r b29d6cfc5a83 htdocs/misc/mogupic.bml
--- a/htdocs/misc/mogupic.bml Wed Sep 08 14:21:07 2010 +0800
+++ b/htdocs/misc/mogupic.bml Wed Sep 08 14:41:32 2010 +0800
@@ -28,7 +28,7 @@ _c?><?_code
my $size = int($GET{'size'});
$size = 640 if $size <= 0 || $size > 640;
- my $upf = LJ::get_upf_scaled(size => $size, userid => $u->id, mogkey =>
"upf_$GET{index}:$u->{userid}");
+ my $upf = LJ::Userpic->get_upf_scaled( size => $size, userid => $u->id,
mogkey => "upf_$GET{index}:$u->{userid}" );
return $ML{'.error.image'} unless $upf;
diff -r 62e8e4716e81 -r b29d6cfc5a83 htdocs/tools/userpicfactory.bml
--- a/htdocs/tools/userpicfactory.bml Wed Sep 08 14:21:07 2010 +0800
+++ b/htdocs/tools/userpicfactory.bml Wed Sep 08 14:41:32 2010 +0800
@@ -42,7 +42,7 @@ _c?>
if (!$w || !$h) {
# we do not have the width and height passed in, we have to compute it
ourselves
- my $upf = LJ::get_upf_scaled(size => $scaledSizeMax, userid =>
$remote->{userid}, mogkey => "upf_$GET{index}:$remote->{userid}");
+ my $upf = LJ::Userpic->get_upf_scaled( size => $scaledSizeMax, userid
=> $remote->userid, mogkey => "upf_$GET{index}:$remote->{userid}" );
($w, $h) = ($upf->[2], $upf->[3]) if ($upf && $upf->[2]);
}
_______________________________________________
dw-changelog mailing list
[email protected]
http://lists.dwscoalition.org/mailman/listinfo/dw-changelog