]> git.uio.no Git - usit-rt.git/blobdiff - share/html/Admin/Tools/Theme.html
Master to 4.2.8
[usit-rt.git] / share / html / Admin / Tools / Theme.html
index c569cd14edd81e2cfc1462cd0e1b19af2ddc6e74..38ef6061e995aa9105e65389949a9089af01b3c1 100644 (file)
@@ -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.</&>
@@ -242,14 +242,82 @@ my $text_threshold = 0.6;
 my @results;
 my $imgdata;
 
+my $colors;
+my $valid_image_types;
+my $analyze_img = sub {
+    return undef if RT->Config->Get('DisableGD');
+    return undef unless Convert::Color->require;
+
+    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");
+    }
+    $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
+    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 %colors;
+
+    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(',',@color);
+            next if $hsl->lightness < 0.1;
+            $colors{$c} ||= { h => $hsl->hue, s => $hsl->saturation, l => $hsl->lightness, cnt => 0, c => $c};
+            $colors{$c}->{cnt}++;
+        }
+    }
+
+    use List::MoreUtils qw(uniq);
+    for (values %colors) {
+        $_->{rank} = $_->{s} * $_->{cnt};
+    }
+    my @top5 = grep { defined and $_->{'l'} and $_->{'c'} }
+                    (sort { $b->{rank} <=> $a->{rank} } values %colors)[0..5];
+    return \@top5;
+};
+
 if (my $file_hash = _UploadedFile( 'logo-upload' )) {
-    my ($id, $msg) = RT->System->SetAttribute( Name => "UserLogo",
-                                                Description => "User-provided logo",
-                                                Content => {
-                                                    type => $file_hash->{ContentType},
-                                                    data => $file_hash->{LargeContent},
-                                                    hash => md5_hex($file_hash->{LargeContent}),
-                                                } );
+    $colors = $analyze_img->($file_hash->{LargeContent});
+
+    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}),
+            colors => $colors,
+        },
+    );
+
     push @results, loc("Unable to set UserLogo: [_1]", $msg) unless $id;
 
     $imgdata = $file_hash->{LargeContent};
@@ -262,6 +330,19 @@ 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');
@@ -291,63 +372,6 @@ if (!$user_css) {
         } @sections
     );
 }
-
-# XXX: move this to some other modules
-
-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...
-    for my $type (qw(Png Jpeg Gif)) {
-        $gd_can{$type}++ if GD::Image->can("newFrom${type}Data");
-    }
-    $valid_image_types = join(", ", map { uc } sort { lc $a cmp lc $b } keys %gd_can);
-
-    # ...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);
-        }
-    }
-}
-
-sub analyze_img {
-    my $img = shift;
-    my $color;
-
-    for my $i (0..$img->width-1) {
-        for my $j (0..$img->height-1) {
-            my @color = $img->rgb( $img->getPixel($i,$j) );
-            my $hsl = Convert::Color->new('rgb:'.join(',',map { $_ / 255 } @color))->convert_to('hsl');
-            my $c = join(',',@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}++;
-        }
-    }
-
-    for (values %$color) {
-        $_->{rank} = $_->{s} * $_->{cnt};
-    }
-    my @top5 = grep { defined and $_->{'l'} and $_->{'c'} }
-                    (sort { $b->{rank} <=> $a->{rank} } values %$color)[0..5];
-    if ((scalar uniq map {$_->{rank}} @top5) == 1) {
-        warn "bad";
-    }
-    return \@top5;
-}
 </%INIT>
 <%ARGS>
 $user_css => ''