Auto-generate thumbnail in equivalent location (unless one has been manually created)


/ Published in: PHP
Save to your folder(s)

Not particularly novel, but quite clean. Allows you to put images in any location on the server and saves having to generate thumbnails at upload time.

The URL to this file should be:

`//`

Valid request types:

* `view` — View the image full-size (don't scale)
* `preview` — View the image at a medium scale
* `thumb` — Show a thumbnail of the image

Images can be JPEGs or PNGs. Broken URLs redirect to a designated 404 image.

Thumbnails and previews will be stored using an identical folder hierarchy inside the `thumbnails` and `previews` folders inside the images folder.


Copy this code and paste it in your HTML
  1. <?php
  2.  
  3. set_error_handler('showBrokenImage');
  4.  
  5. $imagesFolder = 'images/'; // Change this if required to point to your source folder
  6. $brokenImage = $imagesFolder.'brokenimage.png';
  7. $thumbnailHeight = $thumbnailWidth = 80; // Set to the max size of your thumbnail
  8. $previewHeight = $previewWidth = 250; // Set to the max size of your preview images
  9. date_default_timezone_set('Australia/NSW'); // Remove or update this line depending on your PHP.ini settings
  10.  
  11. try {
  12. if(empty($_SERVER['PATH_INFO']) || strpos($_SERVER['PATH_INFO'], ':') !== false || strpos($_SERVER['PATH_INFO'], '..') !== false) {
  13. throw new exception('Invalid path');
  14. }
  15.  
  16. $pathComponents = explode('/', strtolower(trim((isset($_SERVER['PATH_INFO']) && strlen(trim($_SERVER['PATH_INFO'], '/')) ? $_SERVER['PATH_INFO'] : ''), '/')));
  17.  
  18. if($pathComponents[0] === 'thumb') {
  19. $outputWidth = $thumbnailWidth;
  20. $outputHeight = $thumbnailHeight;
  21. } else {
  22. $outputWidth = $previewWidth;
  23. $outputHeight = $previewHeight;
  24. }
  25.  
  26. function mkdir_recursive($pathname, $mode = 0777) {
  27. is_dir(dirname($pathname)) || mkdir_recursive(dirname($pathname), $mode);
  28. return is_dir($pathname) || @mkdir($pathname, $mode);
  29. }
  30.  
  31. $file = $imagesFolder.trim(substr($_SERVER['PATH_INFO'], strlen('/'.$pathComponents[0])), '/');
  32. $fileExtension = strtolower(substr($file, strrpos($file, '.') + 1));
  33.  
  34. if(!is_file($file)) {
  35. throw new exception('Invalid path');
  36. }
  37.  
  38. if(in_array($pathComponents[0], array('thumb', 'preview'))) {
  39. // Generate a smaller image if we haven't already got one
  40. $thumbFile = str_replace($imagesFolder, $imagesFolder.($pathComponents[0] === 'thumb' ? 'thumbnails' : 'previews').'/', $file);
  41. if(!file_exists($thumbFile) && file_exists($file)) {
  42. // Generate a thumbnail
  43. switch($fileExtension) {
  44. case 'jpg':
  45. case 'jpeg':
  46. $sourceImage = imagecreatefromjpeg($file);
  47. break;
  48.  
  49. case 'png':
  50. $sourceImage = imagecreatefrompng($file);
  51. break;
  52. }
  53.  
  54. $sourceX = imagesx($sourceImage);
  55. $sourceY = imagesy($sourceImage);
  56. if ($sourceX > $sourceY) {
  57. $destinationWidth = $outputWidth;
  58. $destinationHeight = $sourceY * ($outputHeight/$sourceX);
  59. } else if ($sourceX < $sourceY) {
  60. $destinationWidth = $sourceX * ($outputWidth/$sourceY);
  61. $destinationHeight = $outputHeight;
  62. } else if ($sourceX == $sourceY) {
  63. $destinationWidth = $outputWidth;
  64. $destinationHeight = $outputHeight;
  65. }
  66.  
  67. $outputImage = imagecreatetruecolor($destinationWidth, $destinationHeight);
  68. imagecopyresampled($outputImage, $sourceImage, 0, 0, 0, 0, $destinationWidth, $destinationHeight, $sourceX, $sourceY);
  69.  
  70. // Make sure the destination folder path exists
  71. mkdir_recursive(dirname($thumbFile));
  72.  
  73. switch($fileExtension) {
  74. case 'jpg':
  75. case 'jpeg':
  76. imagejpeg($outputImage, $thumbFile);
  77. break;
  78.  
  79. case 'png':
  80. imagepng($outputImage, $thumbFile);
  81. break;
  82. }
  83. }
  84.  
  85. $file = $thumbFile;
  86. }
  87.  
  88. if(!file_exists($file)) {
  89. outputImage($brokenImage);
  90. }
  91.  
  92. outputImage($file);
  93. } catch(exception $ex) {
  94. outputImage($brokenImage);
  95. }
  96.  
  97. function outputImage($file) {
  98. $fileExtension = strtolower(substr($file, strrpos($file, '.') + 1));
  99.  
  100. header('Last-Modified: '.@date('r', filemtime($file)));
  101. header('Accept-Ranges: bytes');
  102. switch($fileExtension) {
  103. case 'jpg':
  104. case 'jpeg':
  105. header('Content-Type: image/jpeg');
  106. break;
  107.  
  108. case 'png':
  109. header('Content-Type: image/png');
  110. break;
  111. }
  112. header('Content-Length: '.filesize($file));
  113. flush();
  114. readfile($file);
  115. }
  116.  
  117.  
  118. function showBrokenImage($errno, $errstr) {
  119. global $brokenImage;
  120.  
  121. if(!in_array($errno, array(0, E_STRICT, E_NOTICE))) {
  122. outputImage($brokenImage);
  123. }
  124.  
  125. return true; // Don't execute PHP internal error handler
  126. }
  127.  
  128. ?>

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.