[Rt-commit] rt branch, 4.2/subsample-logo, created. rt-4.2.5-100-gd5d9ff7
Alex Vandiver
alexmv at bestpractical.com
Tue Jul 1 14:56:15 EDT 2014
The branch, 4.2/subsample-logo has been created
at d5d9ff796e1c3fc2701c5b818668bc22ef5c854d (commit)
- Log -----------------------------------------------------------------
commit 8cf72c60b28d8c26ff78e3b8eb9a1a1a62dfb485
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon May 12 13:56:27 2014 -0400
Don't sample every pixel of large logos
The analyze_img code examined every pixel of the image; for large
images, this caused the page to time out, thus making it impossible to
change the image away from the problematically-large one.
Subsample the image if it is more than 200px on a side, by sampling in
an even 200x200 grid. 200px was chosen as an arbitrary upper limit; 40k
points is still a large number to sample, but in testing can be done in
less than 10s.
Fixes #29929.
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index 87ea09e..f96556a 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -331,8 +331,20 @@ sub analyze_img {
my $img = shift;
my $color;
- for my $i (0..$img->width-1) {
- for my $j (0..$img->height-1) {
+ my @wsamples;
+ my @hsamples;
+ if ($img->width > 200) {
+ @wsamples = map { int($img->width*($_/200)) } (0..199);
+ } else {
+ @wsamples = ( 0 .. $img->width - 1 );
+ }
+ if ($img->height > 200) {
+ @hsamples = map { int($img->height*($_/200)) } (0..199);
+ } else {
+ @hsamples = ( 0 .. $img->height - 1 );
+ }
+ for my $i (@wsamples) {
+ for my $j (@hsamples) {
my @color = $img->rgb( $img->getPixel($i,$j) );
my $hsl = Convert::Color->new('rgb:'.join(',',map { $_ / 255 } @color))->convert_to('hsl');
my $c = join(',', at color);
commit c6b3109196d968a2916dd061b0411b39091100f1
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon May 12 14:26:21 2014 -0400
gd_can need not be a global
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index f96556a..abe3bf3 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -61,7 +61,7 @@
<label for="logo-upload"><&|/l&>Upload a new logo</&>:</label>
<input type="file" name="logo-upload" id="logo-upload" /><br />
<div class="gd-support">
-% if (%gd_can) {
+% if ($valid_image_types) {
<&|/l, $valid_image_types &>Your system supports automatic color suggestions for: [_1]</&>
% } else {
<&|/l&>GD is disabled or not installed. You can upload an image, but you won't get automatic color suggestions.</&>
@@ -302,13 +302,13 @@ use List::MoreUtils qw(uniq);
my $has_color_analyzer = eval { require Convert::Color; 1 };
my $colors;
-my %gd_can;
my $valid_image_types;
if (not RT->Config->Get('DisableGD') and $has_color_analyzer) {
require GD;
# Always find out what GD can read...
+ my %gd_can;
for my $type (qw(Png Jpeg Gif)) {
$gd_can{$type}++ if GD::Image->can("newFrom${type}Data");
}
commit 8a6fe3f7c2f82b2a6c5a70494428b98d32aabc16
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon May 12 14:30:26 2014 -0400
Do not install a subroutine into the HTML::Mason::Commands namespace
sub {} in a Mason component makes the sub accessible to every Mason
component, and is highly discouraged. Use a local subref instead.
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index abe3bf3..c2e1e35 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -317,7 +317,7 @@ if (not RT->Config->Get('DisableGD') and $has_color_analyzer) {
# ...but only analyze the image if we have data
if ($imgdata) {
if ( my $img = GD::Image->new($imgdata) ) {
- $colors = analyze_img($img);
+ $colors = $analyze_img->($img);
}
else {
# This has to be one damn long line because the loc() needs to be
@@ -327,7 +327,7 @@ if (not RT->Config->Get('DisableGD') and $has_color_analyzer) {
}
}
-sub analyze_img {
+my $analyze_img = sub {
my $img = shift;
my $color;
@@ -363,7 +363,7 @@ sub analyze_img {
warn "bad";
}
return \@top5;
-}
+};
</%INIT>
<%ARGS>
$user_css => ''
commit 65d5c641e23bbe57cd32e9d8916b0b1765e22ae7
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon May 12 14:34:47 2014 -0400
Replace a needless hashref with a plain hash
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index c2e1e35..542af44 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -329,7 +329,7 @@ if (not RT->Config->Get('DisableGD') and $has_color_analyzer) {
my $analyze_img = sub {
my $img = shift;
- my $color;
+ my %colors;
my @wsamples;
my @hsamples;
@@ -349,16 +349,16 @@ my $analyze_img = sub {
my $hsl = Convert::Color->new('rgb:'.join(',',map { $_ / 255 } @color))->convert_to('hsl');
my $c = join(',', at color);
next if $hsl->lightness < 0.1;
- $color->{$c} ||= { h => $hsl->hue, s => $hsl->saturation, l => $hsl->lightness, cnt => 0, c => $c};
- $color->{$c}->{cnt}++;
+ $colors{$c} ||= { h => $hsl->hue, s => $hsl->saturation, l => $hsl->lightness, cnt => 0, c => $c};
+ $colors{$c}->{cnt}++;
}
}
- for (values %$color) {
+ for (values %colors) {
$_->{rank} = $_->{s} * $_->{cnt};
}
my @top5 = grep { defined and $_->{'l'} and $_->{'c'} }
- (sort { $b->{rank} <=> $a->{rank} } values %$color)[0..5];
+ (sort { $b->{rank} <=> $a->{rank} } values %colors)[0..5];
if ((scalar uniq map {$_->{rank}} @top5) == 1) {
warn "bad";
}
commit 27963f709c2001236cb260fe70ca529577207bda
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon May 12 14:36:15 2014 -0400
Move List::MoreUtils closer to where it is used
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index 542af44..1f64d17 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -298,8 +298,6 @@ if (!$user_css) {
# XXX: move this to some other modules
-use List::MoreUtils qw(uniq);
-
my $has_color_analyzer = eval { require Convert::Color; 1 };
my $colors;
my $valid_image_types;
@@ -354,6 +352,7 @@ my $analyze_img = sub {
}
}
+ use List::MoreUtils qw(uniq);
for (values %colors) {
$_->{rank} = $_->{s} * $_->{cnt};
}
commit 96488e7cf11cd1a4470ceb4a425bac2decc43868
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon May 12 14:36:50 2014 -0400
Remove an unnecessary warning triggered by single-colored logos
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index 1f64d17..37ab6d5 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -358,9 +358,6 @@ my $analyze_img = sub {
}
my @top5 = grep { defined and $_->{'l'} and $_->{'c'} }
(sort { $b->{rank} <=> $a->{rank} } values %colors)[0..5];
- if ((scalar uniq map {$_->{rank}} @top5) == 1) {
- warn "bad";
- }
return \@top5;
};
</%INIT>
commit b6f6e60ad32daddebd594814a61f6e51c2e642cc
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon May 12 14:43:10 2014 -0400
Move GD checking into $analyze_img
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index 37ab6d5..2fcd165 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -297,12 +297,12 @@ if (!$user_css) {
}
# XXX: move this to some other modules
-
-my $has_color_analyzer = eval { require Convert::Color; 1 };
my $colors;
my $valid_image_types;
+my $analyze_img = sub {
+ return undef if RT->Config->Get('DisableGD');
+ return undef unless eval { require Convert::Color; 1 };
-if (not RT->Config->Get('DisableGD') and $has_color_analyzer) {
require GD;
# Always find out what GD can read...
@@ -312,21 +312,18 @@ if (not RT->Config->Get('DisableGD') and $has_color_analyzer) {
}
$valid_image_types = join(", ", map { uc } sort { lc $a cmp lc $b } keys %gd_can);
+ my $imgdata = shift;
+ return undef unless $imgdata;
+
# ...but only analyze the image if we have data
- if ($imgdata) {
- if ( my $img = GD::Image->new($imgdata) ) {
- $colors = $analyze_img->($img);
- }
- else {
- # This has to be one damn long line because the loc() needs to be
- # source parsed correctly.
- push @results, loc("Automatically suggested theme colors aren't available for your image. This might be because you uploaded an image type that your installed version of GD doesn't support. Supported types are: [_1]. You can recompile libgd and GD.pm to include support for other image types.", $valid_image_types);
- }
+ my $img = GD::Image->new($imgdata);
+ unless ($img) {
+ # This has to be one damn long line because the loc() needs to be
+ # source parsed correctly.
+ push @results, loc("Automatically suggested theme colors aren't available for your image. This might be because you uploaded an image type that your installed version of GD doesn't support. Supported types are: [_1]. You can recompile libgd and GD.pm to include support for other image types.", $valid_image_types);
+ return undef;
}
-}
-my $analyze_img = sub {
- my $img = shift;
my %colors;
my @wsamples;
@@ -360,6 +357,7 @@ my $analyze_img = sub {
(sort { $b->{rank} <=> $a->{rank} } values %colors)[0..5];
return \@top5;
};
+$analyze_img->($imgdata);
</%INIT>
<%ARGS>
$user_css => ''
commit 5fba328538f00f226d634a08b36aa211ed4e9624
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon May 12 14:47:22 2014 -0400
Move $analyze_img earlier
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index 2fcd165..5e52d8e 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -242,61 +242,6 @@ my $text_threshold = 0.6;
my @results;
my $imgdata;
-if (my $file_hash = _UploadedFile( 'logo-upload' )) {
- my $my_system = RT::System->new( $session{CurrentUser} );
- my ( $id, $msg ) = $my_system->SetAttribute(
- Name => "UserLogo",
- Description => "User-provided logo",
- Content => {
- type => $file_hash->{ContentType},
- data => $file_hash->{LargeContent},
- hash => md5_hex($file_hash->{LargeContent}),
- },
- );
-
- push @results, loc("Unable to set UserLogo: [_1]", $msg) unless $id;
-
- $imgdata = $file_hash->{LargeContent};
-}
-elsif ($ARGS{'reset_logo'}) {
- RT->System->DeleteAttribute('UserLogo');
-}
-else {
- if (my $attr = RT->System->FirstAttribute('UserLogo')) {
- my $content = $attr->Content;
- if (ref($content) eq 'HASH') {
- $imgdata = $content->{data};
- }
- else {
- RT->System->DeleteAttribute('UserLogo');
- }
- }
-}
-
-if ($user_css) {
- if ($ARGS{'reset_css'}) {
- RT->System->DeleteAttribute('UserCSS');
- undef $user_css;
- }
- else {
- my ($id, $msg) = RT->System->SetAttribute( Name => "UserCSS",
- Description => "User-provided css",
- Content => $user_css );
- push @results, loc("Unable to set UserCSS: [_1]", $msg) unless $id;
- }
-}
-
-if (!$user_css) {
- my $attr = RT->System->FirstAttribute('UserCSS');
- $user_css = $attr ? $attr->Content : join(
- "\n\n" => map {
- join "\n" => "/* ". $_->[0] ." */",
- map { "$_ {}" } @{$_->[1]}
- } @sections
- );
-}
-
-# XXX: move this to some other modules
my $colors;
my $valid_image_types;
my $analyze_img = sub {
@@ -357,7 +302,61 @@ my $analyze_img = sub {
(sort { $b->{rank} <=> $a->{rank} } values %colors)[0..5];
return \@top5;
};
+
+if (my $file_hash = _UploadedFile( 'logo-upload' )) {
+ my $my_system = RT::System->new( $session{CurrentUser} );
+ my ( $id, $msg ) = $my_system->SetAttribute(
+ Name => "UserLogo",
+ Description => "User-provided logo",
+ Content => {
+ type => $file_hash->{ContentType},
+ data => $file_hash->{LargeContent},
+ hash => md5_hex($file_hash->{LargeContent}),
+ },
+ );
+
+ push @results, loc("Unable to set UserLogo: [_1]", $msg) unless $id;
+
+ $imgdata = $file_hash->{LargeContent};
+}
+elsif ($ARGS{'reset_logo'}) {
+ RT->System->DeleteAttribute('UserLogo');
+}
+else {
+ if (my $attr = RT->System->FirstAttribute('UserLogo')) {
+ my $content = $attr->Content;
+ if (ref($content) eq 'HASH') {
+ $imgdata = $content->{data};
+ }
+ else {
+ RT->System->DeleteAttribute('UserLogo');
+ }
+ }
+}
$analyze_img->($imgdata);
+
+if ($user_css) {
+ if ($ARGS{'reset_css'}) {
+ RT->System->DeleteAttribute('UserCSS');
+ undef $user_css;
+ }
+ else {
+ my ($id, $msg) = RT->System->SetAttribute( Name => "UserCSS",
+ Description => "User-provided css",
+ Content => $user_css );
+ push @results, loc("Unable to set UserCSS: [_1]", $msg) unless $id;
+ }
+}
+
+if (!$user_css) {
+ my $attr = RT->System->FirstAttribute('UserCSS');
+ $user_css = $attr ? $attr->Content : join(
+ "\n\n" => map {
+ join "\n" => "/* ". $_->[0] ." */",
+ map { "$_ {}" } @{$_->[1]}
+ } @sections
+ );
+}
</%INIT>
<%ARGS>
$user_css => ''
commit d5d9ff796e1c3fc2701c5b818668bc22ef5c854d
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Mon May 12 14:47:52 2014 -0400
Cache the found colors in the logo attribute
As determining these colors may be time-intensive, and is guaranteed to
not change while the logo itself does not change, the information should
simply be stored alongside the logo.
diff --git a/share/html/Admin/Tools/Theme.html b/share/html/Admin/Tools/Theme.html
index 5e52d8e..1f87127 100644
--- a/share/html/Admin/Tools/Theme.html
+++ b/share/html/Admin/Tools/Theme.html
@@ -304,6 +304,8 @@ my $analyze_img = sub {
};
if (my $file_hash = _UploadedFile( 'logo-upload' )) {
+ $colors = $analyze_img->($file_hash->{LargeContent});
+
my $my_system = RT::System->new( $session{CurrentUser} );
my ( $id, $msg ) = $my_system->SetAttribute(
Name => "UserLogo",
@@ -312,6 +314,7 @@ if (my $file_hash = _UploadedFile( 'logo-upload' )) {
type => $file_hash->{ContentType},
data => $file_hash->{LargeContent},
hash => md5_hex($file_hash->{LargeContent}),
+ colors => $colors,
},
);
@@ -327,13 +330,25 @@ else {
my $content = $attr->Content;
if (ref($content) eq 'HASH') {
$imgdata = $content->{data};
+ $colors = $content->{colors};
+ unless ($colors) {
+ # No colors cached; attempt to generate them
+ $colors = $content->{colors} = $analyze_img->($content->{data});
+ if ($content->{colors}) {
+ # Found colors; update the attribute
+ RT->System->SetAttribute(
+ Name => "UserLogo",
+ Description => "User-provided logo",
+ Content => $content,
+ );
+ }
+ }
}
else {
RT->System->DeleteAttribute('UserLogo');
}
}
}
-$analyze_img->($imgdata);
if ($user_css) {
if ($ARGS{'reset_css'}) {
-----------------------------------------------------------------------
More information about the rt-commit
mailing list