Question

I am trying to create thumbnail pics using GD lib in Cake PHP.

I can write the resized thumbnail to the tmp directory, and create the sensible URL to show the image from the tmp directory:

//set up empty GD resource  
$tmp = imagecreatetruecolor(200*$iw/$ih, 200);
//create thumbnail image in the empty GD resource
imagecopyresampled($tmp, $src, 0, 0, 0, 0,200*$iw/$ih, 200, $iw, $ih);
//build full path to thumbnail in the cakephp tmp directory
$thumbfile = APP.'tmp/thumb.jpg';
//build URL path to the same thumbnail
$thumblink = $this->webroot.'tmp/thumb.jpg';
//write jpeg to the tmp directory
$return=imagejpeg($tmp,$thumbfile);
//write out the image to client browser
echo "<img=\"$thumblink\" alt=\"thumb\" height=\"200\" width=\"200*$iw/$ih\">";

The thumbnail gets created and written to the tmp directory, but when I try to access the URL I get the following error message:

Error: TmpController could not be found.
Error: Create the class TmpController below in file: app/Controller/TmpController.php

Obviously I have a routing error - Cake tries to call the tmp controller, in stead of looking in the tmp direcectory. How can I fix this, or is there an alternative way to serve temporary thumbnails using GD lib? I am planning to create unique thumbnails per session or user, but I need to get this working first.

Routing in Config/routes.php:

Router::connect('/', array('controller' => 'MsCake', 'action' => 'index'));
Router::connect('/pages/*', array('controller' => 'pages'));
CakePlugin::routes();

I looked at ThumbnailHelper, but that doesn't use GD Lib. I also need to be able to access files stored on non-apache accessible directories from outside, but I can't even access any temporary symbolic links to get to them. eg.

  • create a temporary symbolic link in the tmp directory, pointing to the file in question.
  • create a HTML link, pointing to the symbolic link using $this->webroot.'tmp/link-to-myfile', as above

...and I get the same error as above - Error: TmpController could not be found.

Was it helpful?

Solution

Don't do that

If you do anything to make files in the tmp dir web-accessible - you're severely lowering your site's security. Things in the tmp directory are never supposed to be web accessible.

Put your images in the webroot

A better idea is to put your temporary images in the webroot directory - which is the only directory that is ordinarily web accessible. For example:

$filename = md5($userId);
$thumbfile = APP.'webroot/img/cache/' . $filename . '.jpg';

...
$url = '/img/cache/' . $filename . '.jpg';

Or route to a controller action

Alternatively, route to a controller action to handle the request using the media view class. Note however though, that serving images with php is not free - there can be a noticable delay while your request is processed - where'as pointing at a static file does not have this cost/risk since it's just the webserver taking care of serving the content.

OTHER TIPS

Since it's temporary, what you could do is to display the image as a data url instead of to the tmp directory, like so (replace from after imagecopyresampled() call):

ob_start();
imagepng($tmp);
$contents =  ob_get_contents();
ob_end_clean();
imagedestroy($tmp);


//write out the image to client browser
echo "<img src='data:image/png;base64,".base64_encode($contents)."' alt='thumb' height='200' width='".(200*$iw/$ih)."'>";

This uses a bit more bandwidth since the image is base64 encoded rather than sent as binary.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top