Timthumb and Ajax
Timthumb is a great tool for cropping/resizing images dynamically at the time the page loads. But what if you want to update the src of an image tag with a new image, for example, in an image carousel?
You can use timthumb via an ajax call, but the resulting data is binary so you have to do two things: 1) convert the binary to base64, 2) add a prefix to the src attribut it to tell the browser how to handle it.
So converting the binary data to base64 is done inside the timthumb script. What I did was check for a param in the GET and, if present, I converted the data to base64. In the timthumb serveCacheFile() function I replaced these line:
$imageDataSize = filesize($this->cachefile) - (strlen($this->filePrependSecurityBlock) + 6); $this->sendImageHeaders($imgType, $imageDataSize); $bytesSent = @fpassthru($fp);
with this:
$imageDataSize = filesize($this->cachefile) - (strlen($this->filePrependSecurityBlock) + 6);
if (isset($_GET['marko'])){
// Look out for the 'marko' flag. This is serving a base64 encoded string so
// that an HTML image tag can display the file in it's src attribute. Useful
// when Ajax is needed to resize files for a carousel.
$fsize = filesize($this->cachefile);
$binary = fread($fp,$fsize);
$bin64 = base64_encode($binary);
fclose($fp);
echo 'data:image/bmp;base64,'.$bin64;
return true;
} else {
$this->sendImageHeaders($imgType, $imageDataSize);
$bytesSent = @fpassthru($fp);
}
Then in my HTML page I have a bit of jQuery as follows:
load_link = encodeURI("&src=" + link + "&h=194&w=263&marko=1");
$.get('/images/timthumb.php', load_link, updateLink);
function updateLink(data) {
$('#flickr-first-photo').attr('src',data);
}
Where the ‘link’ var is the external file, in my case, a flickr hosted image. You can see I’m passing marko=1 in as a GET param. This is my flag that I pick up in the timthumb.php script. The function updateLink() adds the base64 encoded data to the src of the image with id flickr-first-photo.
