Bod has asked for the wisdom of the Perl Monks concerning the following question:
I again seek your wisdom fellow Monks...
As part of the website for my partner's artwork, I am producing two copies of each image that she will upload. One is a small thumbnail with quite high JPEG compression so that it is deliberately pixelated if it is enlarged. The other image is high resolution and large, but with a watermark copyright notice on it. I am using GD for the image processing and Image::Resize to make the sizing easier.
GD is being used because I know my way around it better than the alternatives like Image::Magick and I know GD better because it is available to me by default.
All the resizing works fine and I am able to add a watermark in two parts to get two different font sizes. However, regardless of what I add in the first parameter of ->stringFT() the text is always black. This is fine for some images...
this watermark looks fine
But the black watermark doesn't work very well on artwork where a significant amount of the background is black or close to black.
this watermark doesn't look right
My first thought was to try to have semi-transparent text for the watermark. However, searching suggests that this isn't possible although I haven't found anything which categorically rules it out. So instead I thought of trying to read the general "darkness" of areas of the background where the watermark is going to be and programmatically choose a colour that will contrast against this. Detecting the "darkness" seems far from trivial...
Here is the code...
Can you suggest either a better way to accomplish what I am trying to do or a relatively simple way to detect how dark the background is, select a colour for the text that will show up on that background and then actually create text in that colour?sub XHRupload { no strict 'subs'; my $full; my $image = Image::Resize->new(GD::Image->new($file{'joolzimage', +'file'})); if ($image->width() > 1800) { $full = $image->resize(1800, 99999); } else { $full = $image->gd(); } my $year = (localtime)[5] + 1900; my $watermark = 'Artwork by Joolz'; my $copyright = "copyright $year"; # Centre text components and centre on image my @bounds = new GD::Image->stringFT('silver', "$ENV{'DOCUM +ENT_ROOT'}/cgi-bin/Image/watermark.ttf", 140, 0.18, 0, 0, $watermark) +; my $left = ($full->width() / 2) - (($bounds[2] - $bounds +[0]) / 2) + 5; my $top = ($full->height() / 2); $full->stringFT('white', "$ENV{'DOCUMENT_ROOT'}/cgi-bin/Image/wate +rmark.ttf", 140, 0.18, $left, $top, $watermark); @bounds = new GD::Image->stringFT('silver', "$ENV{'DOCUMENT +_ROOT'}/cgi-bin/Image/watermark.ttf", 80, 0.18, 0, 0, $copyright); $left = ($full->width() / 2) - (($bounds[2] - $bounds[0] +) / 2) + 5; $top = ($full->height() / 2) + 120; $full->stringFT('blue', "$ENV{'DOCUMENT_ROOT'}/cgi-bin/Image/water +mark.ttf", 80, 0.18, $left, $top, $copyright); open my $fh, '>', "$ENV{'DOCUMENT_ROOT'}/artwork/full/$data{'id'}. +jpg"; print $fh $full->jpeg(100); close $fh; my $thumb = $image->resize(300, 1000); open $fh, '>', "$ENV{'DOCUMENT_ROOT'}/artwork/thumbs/$data{'id'}.j +pg"; print $fh $thumb->jpeg(32); close $fh; print "Content-type: text/plain\n\n"; print $data{'id'}; exit 0; }
As always, any other advice on improving my code would be welcome.
|
|---|