For various reasons, you might find that you wish to find your whole data stream, and post-process it before you send it to the browser. A practical reason is to support ‘Content-Length:’ to increase speed, and cachability of your program, or to manipulate the data again before it’s fully sent to the client. Sometimes, this can be difficult.

For this example, we’ll examine my silly little ‘who are you’ image generator. (Note that this old version does not have features of the new one, but they’re highly semantical (the image buffering and code to display the user’s country, as well as cleaning the code up a bit. I love tenary operators!

In PHP, you want to buffer your content with ob_start().

Here’s a snippit of my local copy’s functioning code: ...
ob_start();
imagejpeg($im);
$imageBuffer = ob_get_contents();
ob_end_clean();
header(‘Last-Modified: ’.gmdate(‘D, d M Y H:i:s’).’ GMT’);
header(‘Content-Length: ’. strlen($imageBuffer));
header(“Content-type: image/jpeg”);
echo(”$imageBuffer”);
imagedestroy($im);

As you see, I tell PHP to begin buffering my output. Then, I tell PHP to create my image with the data stored in $im. I then read that data into a temporary buffer, rather than wasting overhead with a temporary file. I tell it to cleanly end the buffer, and begin the process of displaying my image. I obtain the size of the image, which will be used to specify the length of the image, display it, and cleanly exit.

It is possible (and rather often) for images and other data to be created with no buffering, but then the only trivial solution (I can think of) would be to cause further overhead to obtain the size of our generated image. In this case, it’s not overly necessary, but for a product, as say, a thumbnail generator, I’d strongly suggest buffering, as opposed to creating an interm tempfile.

A sample function for such (say, adding watermarks) might look like:

function waterMark($originalFile, $watermarkFile) { $watermarkSource = imagecreatefromjpeg($watermarkFile); $originalSource = imagecreatefromjpeg($originalFile); ... imagecopymerge($originalSource, $watermarkSource, $originalSourceSizeX, $originalSourceSizeY, 0, 0, $fileWidth, $fileHeight, 100); ob_start(); imagejpeg($originalSource); $imageBuffer = ob_get_contents(); ob_end_clean(); imagedestroy($originalSource); imagedestroy($watermarkSource); return $imageBuffer; }

Thus, you’ll have your watermarked image returned to you as a string; to write out to a file, stuff into an array, or if you’re really sadistic, dumped into a SQL database! :)

Design notes: I chose to set the Last-Modified header as to not cache the image; after all, it is entirely dynamic. I also decided to use ‘echo’ rather than ‘print’ for a rather marginal speed increase, as it does not set a return value.

Peter Veenstra, (Qbix, DOSBox) has been so kind as to donate cash to help cover the cost of my webhosting. Many thanks to Peter and the entire DOSBox crew for this gift.

Per request (no, really, I did have one!), I’ve setup a PayPal donate button on my software download page.

Update: The link was removed on Sept. 1st, 2005. Please donate to the Salvation Army. Any funds donated to me throughout the rest of 2005 will be sent in care of the Salvation Army to assist families (formerly) in New Orleans.

I’ve had a few inquries in the past about moving from the ‘old standard’ Stuffit format for my bundles, as Apple no longer offers Stuffit Expander with MacOS X.

I refuse to embrace the .Zip broken-standard which Apple offers with MacOS X 10.3 – it not only stores things in a rather hackish way, but anyone who doesn’t useApple’s BOMArchiver to uncompress it will end up with useless and broken data.

I’ve created a poll which will run for the next two months. I prefer .tar.bz2 (tbz) personally, but this would have issues with older MacOS X 9 archives, or programs with seperate resource forks.

Cast your vote!