fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2010-09-08 06:42 am

[dw-free] cleaning up userpics code

[commit: http://hg.dwscoalition.org/dw-free/rev/b29d6cfc5a83]

http://bugs.dwscoalition.org/show_bug.cgi?id=513

Move icon resizing code to the LJ::Userpic package.

Patch by [personal profile] kareila.

Files modified:
  • bin/worker/userpic-resize-gm
  • cgi-bin/LJ/Userpic.pm
  • cgi-bin/ljuserpics.pl
  • htdocs/editicons.bml
  • htdocs/misc/mogupic.bml
  • htdocs/tools/userpicfactory.bml
--------------------------------------------------------------------------------
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]);
     }
 
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
No Subject Icon Selected
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org