December 1st, 2007

I've written about this previously, but worth repeating. CSS can be dynamically created using a PHP application, as long as the content type is set to CSS:

<?php // declare the output of the file as CSS header('Content-type: text/css'); ?>

The style sheet can then be used directly or imported into another:

@import "photographs.php"; I use this feature to randomly assign a background image for my header and also to access the color of select pixels in the image in order to colorize the theme based on image. I based the points on the photographer's "rule of thirds", which puts the focus on the photo along an imaginary line, either along the top or bottom horizontal third, or the left or right horizontal third. I also pick a pixel directly in the middle of the image. I could test all pixels and find the most common colors used, but the amount of processing is prohibitive. I've haven't seen this algorithm fail when it comes to creating a compatible color set, yet. fishie.jpeg (JPEG Image, 818x195 pixels) I use the built-in graphical GD functions in PHP to pick the color points, as well as find the size of my background image, and adjust the header accordingly. I could also have used IMagick, the PHP-based wrapper for ImageMagick, but GD is almost universally available on web hosts, while IMagick is not.

// create a working image 
$im = imagecreatefromjpeg($imgname);

// get image height and width
$height = imagesy($im);
$width = imagesx($im);

// sample five points in the image, based on rule of thirds and center
$rgb = array();

$topx = round($height / 3);
$bottomx = round(($height / 3) * 2);
$lefty = round($width / 3);
$righty = round(($width / 4) * 2);
$centerx = round($height / 2);
$centery = round($width / 2);

$rgb[1] = imagecolorat($im, $topx,$lefty);
$rgb[2] = imagecolorat($im, $topx, $righty);
$rgb[3] = imagecolorat($im, $bottomx, $lefty);
$rgb[4] = imagecolorat($im, $bottomx, $righty);
$rgb[5] = imagecolorat($im, $centerx, $centery);


// extract each value for r, g, b
$r = array();
$g = array();
$b = array();

$ct = 0; $val = 5000;
// process points
for ($i = 1; $i <= 5; $i++) {
   $r[$i] = ($rgb[$i] >> 16) & 0xFF;
   $g[$i] = ($rgb[$i] >> 8) & 0xFF;
   $b[$i] = $rgb[$i] & 0xFF;

   // find darkest color
   $tmp = $r[$i] + $g[$i] + $b[$i];
   if ($tmp < $val) {
       $val = $tmp;
       $ct = $i;
   }

}

   printf(".color1 { fill: rgb($r[1],$g[1],$b[1]); stroke: rgb($r[4],$g[4],$b[4]); }\n");
   printf(".color2 { fill: rgb($r[2],$g[2],$b[2]); stroke: rgb($r[3],$g[3],$b[3]); }\n");
   printf(".color3 { fill: rgb($r[3],$g[3],$b[3]); stroke: rgb($r[2],$g[2],$b[2]); }\n");
   printf(".color4 { fill: rgb($r[4],$g[4],$b[4]); stroke: rgb($r[1],$g[1],$b[1]); }\n");
   printf(".color5 { fill: rgb($r[5],$g[5],$b[5]); }\n");

   printf("stop.begin { stop-color: rgb($r[1],$g[1],$b[1]); }\n");
   printf("stop.middle   { stop-color: rgb($r[5],$g[5],$b[5]); }\n");
   printf("stop.end { stop-color: rgb($r[4],$g[4],$b[4]); }\n");
   printf(".nameExpanded, .nameCollapsed { background-color: rgb($r[4],$g[4],$b[4]); } \n");
   printf(".column-post h2, .column-post h2 a, .firstpost, 
                .firstpost a { color: rgb($r[$ct],$g[$ct],$b[$ct]); } \n");

To ensure that the title and title bars contrast strongly enough to be viewable, I test the selected colors for the 'darkest', ie the less saturated of colors. Adding up the RGB separate values does the trick: a value of RGB(0,0,0) totals to 0, while one for RGB(255,255,255) totals to 765. Everything else falls in between.

Again, the reason for doing this type of adjustment is not only to add an interesting, and changing element, to the site interface, but also to demonstrate what can be done with both images and CSS. Neither is static, and none of the modifications requires scripting on the client, and many of the modifications aren't impacted by browser type.

For more details on the processing, access the viewable copy of the PHP program.

October 22nd, 2007

Tim Bray wrote on style progressions in programming languages. He hints that it would be nice that JavaScript and Erlang would get it together, and lists ASP, Cold Fusion, and PHP as the 'flawed' founders to that beautiful, polished successor, Rails, and Perl the flawed founder to Python and Ruby.

I find it fascinating when a person marks as 'flawed' the languages that have, literally, defined not only the web but application development of all forms. Perhaps the metric shouldn't be on syntax, form, or function, but on usability. From a usability perspective, given degree of use today, we could switch his tables to:

Programming-language Waves
'Perfect', but barely used** 'Flawed', but simple, approachable, powerful, popular
Higher-Level *Ruby (every time I see 'Ruby' I mentally add, Mama's precious little…) Perl
Client side code (The to-be-created scripting language that will take a nice, clean, easy to use language and morph it until it satisfies the purists, while breaking faith with the millions of users just trying to do a job) JavaScript
Object Oriented Java (bloated beyond recognition with senseless additions and overly complex infrastructures) C++ (which can kick Java's ass performance and resource wise)
Web-Centric Rails (you know that thing they used for the one application?) Cold Fusion, ASP and ASP.NET, PHP

I agree that C is a polished successor–once FORTRAN is no longer used for this nation's defense systems, and COBOL applications finally vanish after their many decades of use. Even Perl, which gets slammed much today has a legacy deserving of respect–not to mention a legacy of continued use. As for Erlang, eh. Wanna be. Toy. Doozer. (Remember Eiffel? Yeah, you get the picture.)

What Tim is missing is that it's not the language that's responsible for crappy code–it's the people who use the language. There is beautiful PHP and there's crappy Ruby. The only difference between the two is that, thankfully, there's a lot more beautiful PHP than there is crappy Ruby.

*I'm giving Python a slide because Python has fairly widespread use today.

**updated Yes, I'm aware of Java's strong corporate presence, as well as support for desktop applications. "Barely used" was poetic license on my part. Here, here's a thrown exception. Knock yourself out.