Page decorations should be subtle and not distracting. I find that gentle gradients used as backgrounds satisfy this criteria. But making gradients is laborious. So I wrote a script to do it for me.
The script is simple but also quite powerful. Here is some example usage:
Blue to red moving left, produced with /cgi-bin/gradient.cgi?width=100&height=30&from=00f&to=f00&dir=left
Green to yellow moving up, produced with /cgi-bin/gradient.cgi?width=100&height=30&from=0f0&to=ff0&dir=up
There are five mandatory arguments for the CGI:
Argument | Example | Description |
---|---|---|
width | 150 | Width of image in pixels |
height | 150 | Height of image in pixels |
from | F12 | Starting color in 12-bit hex (See Notes below) |
to | 0E8 | Ending color in 12-bit hex (See Notes below) |
dir | left | Direction, one of "left", "right", "up", or "down" |
I chose to use a three character hexadecimal representation (12-bit) of the RGB color triplet for simplicities sake. I've found that in most situations, specifying six hex characters (24-bits) distracts and impedes a fast-and-loose creative process.
#!/usr/local/bin/perl # # Gradient making program. # # Author: Michal Guerquin (michalg@gmail.com) # Date: January, 2005 # use CGI::Carp qw(fatalsToBrowser); use CGI; use GD; use strict; sub mkramp #($im, $steps, $r0, $g0, $b0, $r1, $g1, $b1) { my ($im, $steps, $r0, $g0, $b0, $r1, $g1, $b1) = @_; my $dr = ($r1 - $r0) / $steps; my $dg = ($g1 - $g0) / $steps; my $db = ($b1 - $b0) / $steps; my @ramp = (); my $r = $r0; my $g = $g0; my $b = $b0; for (my $i=0; $i<$steps; $i++) { @ramp = (@ramp, $im->colorAllocate($r,$g,$b)); $r += $dr; $g += $dg; $b += $db; } return @ramp; } my $theCGI = new CGI; my $from = $theCGI->param("from"); my $to = $theCGI->param("to"); my $width = $theCGI->param("width"); my $height = $theCGI->param("height"); my $dir = $theCGI->param("dir"); if (not ($from =~ /[0-9a-fA-F]{3}/)) { die "Missing or bad 'from'"; } if (not ($to =~ /[0-9a-fA-F]{3}/)) { die "Missing or bad 'to'"; } if (not ($width =~ /[0-9]+/)) { die "Missing or bad 'width'"; } if (not ($height =~ /[0-9]+/)) { die "Missing or bad 'height'"; } if (not ($dir eq "left" or $dir eq "right" or $dir eq "up" or $dir eq "down")) { die "Missing or bad 'dir'"; } $from =~ s/(.)(.)(.)/$1\|$2\|$3/; my($from_r,$from_g,$from_b)=split(/\|/,$from); $to =~ s/(.)(.)(.)/$1\|$2\|$3/; my($to_r,$to_g,$to_b)=split(/\|/,$to); my $from_r = 16*hex($from_r) + hex($from_r); my $from_g = 16*hex($from_g) + hex($from_g); my $from_b = 16*hex($from_b) + hex($from_b); my $to_r = 16*hex($to_r) + hex($to_r); my $to_g = 16*hex($to_g) + hex($to_g); my $to_b = 16*hex($to_b) + hex($to_b); my $steps = 1; if ($dir eq "down") { $steps = $height; } if ($dir eq "up") { $steps = $height; } if ($dir eq "left") { $steps = $width; } if ($dir eq "right") { $steps = $width; } # create a new image GD::Image->trueColor(1); my $im = new GD::Image($width,$height); my @ramp = &mkramp($im, $steps, $from_r,$from_g,$from_b, $to_r,$to_g,$to_b); if ($dir eq "down") { for (my $i=0; $i<$height; $i++) { $im->line(0,$i,$width,$i,$ramp[$i]); } } elsif ($dir eq "up") { for (my $i=0; $i<$height; $i++) { $im->line(0,$i,$width,$i,$ramp[$height-$i-1]); } } elsif ($dir eq "left") { for (my $i=0; $i<$width; $i++) { $im->line($i,0,$i,$height,$ramp[$i]); } } elsif ($dir eq "right") { for (my $i=0; $i<$width; $i++) { $im->line($i,0,$i,$height,$ramp[$width-$i-1]); } } # make sure we are writing to a binary stream binmode STDOUT; print "Content-type: image/jpeg\n\n"; # Convert the image to JPG and print it on standard output print $im->jpeg(100);
Ideas for future improvements:
https://michal.guerquin.com/gradient.html
, updated 2005-01-20 03:08 EST