Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 515 lines (439 sloc) 23.894 kb
ead2645 @MattWilcox Initial Commit
MattWilcox authored
1 <?php
2 /* FILE INFO ----------------------------------------------------------------------------------------------------------
b38a69b @MattWilcox Clarified PHP comments
MattWilcox authored
3 http://adaptive-images.com | Twitter: @responsiveimg
c7ceb2a @MattWilcox re-branding to Adaptive-Images
MattWilcox authored
4
f937840 @MattWilcox Changed the default $mobile_first to FALSE due to Firefox bug
MattWilcox authored
5 version 1.3 beta (2011/08/31) ------------------------------------------------------------
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
6 NEW FEATURES
7 * Added support for Mobile First philosophy (see CONFIG, $mobile_first)
8
9 NOTES
10 When $mobile_first is set to TRUE it means the mobile sized version of the requested
11 image will be sent in the event that no cookie is set (likely because JavaScript is
12 unavailable). If FALSE, the original image is sent.
b38a69b @MattWilcox Clarified PHP comments
MattWilcox authored
13
14 There is a known problem with Firefox on a first visit to a site where $mobile_first
15 is TRUE. It doesn't set the cookie fast enough, so the very first load sends the mobile
16 size image. All page loads after are fine. Opera, Safari, and Chrome all work OK.
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
17
18 version 1.2.2 (2011/08/30) ------------------------------------------------------------
19 NEW FEATURES
20 * Unsupported no-javascript solution (see instructions.htm)
21
c7ceb2a @MattWilcox re-branding to Adaptive-Images
MattWilcox authored
22 version 1.2.1 (2011/08/26) ------------------------------------------------------------
23 NO NEW FEATURES
24 I have re-branded Responsive-Images to "Adaptive-Images", firstly to help distinguish
25 this project from the identically named project by Filament Group, and secondly
b662de3 @MattWilcox Just correcting some dodgy spelling in the comments
MattWilcox authored
26 because it's a more appropriate name. This system actively adapts existing images as
27 well as "responding" to the visitors viewport to serve an appropriately sized version.
c7ceb2a @MattWilcox re-branding to Adaptive-Images
MattWilcox authored
28
29 NOTES
30 The project is now available on GitHub for those who wish to track it there:
31 https://github.com/MattWilcox/Adaptive-Images
32
ead2645 @MattWilcox Initial Commit
MattWilcox authored
33 version 1.2 (2011/08/21) ------------------------------------------------------------
34 Contributions by Fabian Beiner, with thanks :)
35 NEW FEATURES
36 * Support for PNG and GIF images
37 * Added ability to sharpen re-scaled images (see CONFIG, $sharpen)
38 BUG FIXES
39 * Better extension detection (.jpeg was failing)
40 * First-run Firefox bug fixed. The JS must be in-line, in the <head>!
41 DETAILS:
42 Firefox (and potentially others, but not observed anywhere else) was requesting
43 the first <img> before it loaded the external javascript file, even when in the
44 <head>. This caused Firefox to load the full-resolution image the very first
45 time the site was visited. All subsequent page views were fine.
46 OTHER IMPROVEMENTS
47 * Cleaned up the .htaccess file and included clear comments on use
48 * Vastly improved instructions and examples on the downloadable zip
49 * Since 1.1 fixed issues with browser cache, default cache time now set to 7 days
50 * Refactored PHP code
51
52 version 1.1 (2011/08/16) ------------------------------------------------------------
53
54 NEW FEATURES
55 * Re-engineered the size detection methodology.
56
57 Now detects maximum possible screen size of the device instead of the current
58 window size. This removes the problem of visitors with small windows caching
59 small images to the browser, then upon maximising the browser having too small
60 images for the new screen size. It also simplifies the JS back down to its
61 original "just dump the size into a cookie" functionality.
62
63 This update removes the following:
64
65 * All JS config options
66
67 version 1.0 (2011/08/09) ------------------------------------------------------------
68
69 NEW FEATURES
70 * Headers sent along with the image, for browser side caching (see CONFIG, $browser_cache)
71 * JavaScript responds to window re-sizes, requests higher res images if required
72 BUG FIXES
73 * Fixed the MIME type for JPG's (image/jpeg not image/jpg)
74
75 beta 2 (2011/08/04) -----------------------------------------------------------------
76
77 NEW FEATURES
78 * Added the ability to control generated image quality (see CONFIG, $jpg_quality)
79 * Added configurable resolution breakpoints (see CONFIG, $resolutions)
80 * Optional Cache checking - defaults to on (see CONFIG, $watch_cache)
81 BUG FIXES
82 * The PHP now checks that the GD extension is loaded before proceeding
83 * Clarified comments further
84
85 beta 1 (2011/08/01) -----------------------------------------------------------------
86
87 NEW FEATURES
88 * Initial public release
89 * Commented the PHP for public consumption
90 * Added user-configurable cache directory (see CONFIG, $cache_path)
91 BUG FIXES
92 * Didn't generate downscaled images due to typo
93
94 /* CONFIG ----------------------------------------------------------------------------------------------------------- */
95
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
96 $resolutions = array(1382, 992, 768, 480); // the resolution break-points to use (screen widths, in pixels)
5725f37 @MattWilcox Fixing typo's in the default configuration and instructions
MattWilcox authored
97 $cache_path = "ai-cache"; // where to store the generated re-sized images. This folder must be writable.
ead2645 @MattWilcox Initial Commit
MattWilcox authored
98 $jpg_quality = 80; // the quality of any generated JPGs on a scale of 0 to 100
99 $sharpen = TRUE; // Shrinking images can blur details, perform a sharpen on re-scaled images?
100 $watch_cache = TRUE; // check that the responsive image isn't stale (ensures updated source images are re-cached)
101 $browser_cache = 60*60*24*7; // How long the BROWSER cache should last (seconds, minutes, hours, days. 7days by default)
f937840 @MattWilcox Changed the default $mobile_first to FALSE due to Firefox bug
MattWilcox authored
102 $mobile_first = FALSE; // If there's no cookie deliver the mobile version (if FALSE, delivers original resource)
ead2645 @MattWilcox Initial Commit
MattWilcox authored
103
104 /* END CONFIG ----------------------------------------------------------------------------------------------------------
105 ------------------------ Don't edit anything after this line unless you know what you're doing -------------------------
106 --------------------------------------------------------------------------------------------------------------------- */
107
108 /* get all of the required data from the HTTP request */
109 $document_root = $_SERVER['DOCUMENT_ROOT'];
110 $requested_uri = (stripos($_SERVER['REQUEST_URI'], '?')) ? substr($_SERVER['REQUEST_URI'], 0, stripos($_SERVER['REQUEST_URI'], '?')) : $_SERVER['REQUEST_URI'];
111 $requested_file = basename($requested_uri);
112 $extension = strtolower(pathinfo($requested_file, PATHINFO_EXTENSION)); // filename extension of the passed uri
113
114 /* set up some variables we'll use later */
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
115 switch ($extension) { // sort out MIME types for different file types
ead2645 @MattWilcox Initial Commit
MattWilcox authored
116 case png:
117 $mime_type = "Content-Type: image/png";
118 break;
119 case gif:
120 $mime_type = "Content-Type: image/gif";
121 break;
122 default:
123 $mime_type = "Content-Type: image/jpeg";
124 break;
125 }
126
127 /* helper function: Send headers and returns an image. */
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
128 function sendImage($filename, $mime_type, $browser_cache) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
129 header($mime_type);
130 header("Pragma: public");
131 header("Cache-Control: maxage=".$browser_cache);
132 header('Expires: '.gmdate('D, d M Y H:i:s', time()+$browser_cache).' GMT');
133 header('Content-Length: '.filesize($filename));
134 readfile($filename);
135 exit();
136 }
137
138 /* sharpen images function */
139 function findSharp($intOrig, $intFinal) {
140 $intFinal = $intFinal * (750.0 / $intOrig);
141 $intA = 52;
142 $intB = -0.27810650887573124;
143 $intC = .00047337278106508946;
144 $intRes = $intA + $intB * $intFinal + $intC * $intFinal * $intFinal;
145 return max(round($intRes), 0);
146 }
147
148 /* check that PHP has the GD library available to use for image re-sizing */
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
149 if (!extension_loaded('gd')) { // it's not loaded
ead2645 @MattWilcox Initial Commit
MattWilcox authored
150 if (!dl('gd.so')) { // and we can't load it either
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
151 if (!file_exists($document_root.$requested_uri)) { // and the requested file doesn't exist
ead2645 @MattWilcox Initial Commit
MattWilcox authored
152 header("Status: 404 Not Found");
153 exit();
154 }
155
156 // no GD available, but the requested image exists, so deliver that straight up
157 sendImage($document_root.$requested_uri,$mime_type,$browser_cache);
158 }
159 }
160
161 /* Check to see if a cookie exists */
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
162 if (!$_COOKIE["resolution"]) { // no cookie
163 if (!file_exists($document_root.$requested_uri)) { // and the requested file doesn't exist either
ead2645 @MattWilcox Initial Commit
MattWilcox authored
164 header("Status: 404 Not Found");
165 exit();
166 }
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
167 /* there isn't a cookie (likely no JS available) */
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
168 if ($mobile_first !== TRUE) { // We want to send the original resolution image if JS is disabled
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
169 sendImage($document_root.$requested_uri,$mime_type,$browser_cache);
170 }
171 else { // We want to send the mobile resolution if JS is disabled
172 sort($resolutions); // make sure the supplied break-points are in ascending size order
173 $resolution = $resolutions[0]; // we only want the smallest supported break-point (the mobile resolution)
174
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
175 if (file_exists($document_root."/$cache_path/$resolution/".$requested_uri)) { // it exists cached at that size
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
176 sendImage($document_root."/$cache_path/$resolution/".$requested_uri,$mime_type,$browser_cache);
177 }
178 else { // it doesn't exist at that size cached
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
179 if ($watch_cache) { // if cache watching is enabled, compare cache and source modified dates to ensure the cache isn't stale
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
180 $cache_date = filemtime($document_root."/".$cache_path."/".$resolution."/".$requested_uri);
181 $source_date = filemtime($document_root.$requested_uri);
182
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
183 if ($cache_date < $source_date) { // the source file has been replaced since the cache was generated
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
184 // Check the image dimensions
185 $source_image = $document_root.$requested_uri;
186 $dimensions = GetImageSize($source_image);
187 $width = $dimensions[0];
188 $height = $dimensions[1];
189
190 // Do we need to downscale the image?
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
191 if ($width <= $resolution) { // no, because the width of the source image is already less than the client width
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
192 sendImage($document_root.$requested_uri);
193 }
194
195 // We need to resize the source image to the width of the resolution breakpoint we're working with
196 $ratio = $height/$width;
197 $new_width = $resolution;
198 $new_height = ceil($new_width * $ratio);
199
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
200 switch ($extension) {
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
201 case png:
202 $src = @ImageCreateFromPng($source_image); // original image
203 break;
204 case gif:
205 $src = @ImageCreateFromGif($source_image); // original image
206 break;
207 default:
208 $src = @ImageCreateFromJpeg($source_image); // original image
209 break;
210 }
211
212 $dst = ImageCreateTrueColor($new_width,$new_height); // re-sized image
213 ImageCopyResampled($dst, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height); // do the resize in memory
214
215 // sharpen the image?
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
216 if ($sharpen == TRUE) {
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
217 $intSharpness = findSharp($width, $new_width);
218 $arrMatrix = array(
219 array(-1, -2, -1),
220 array(-2, $intSharpness + 12, -2),
221 array(-1, -2, -1)
222 );
223 imageconvolution($dst, $arrMatrix, $intSharpness, 0);
224 }
225
226 // check the path directory exists and is writable
227 $directories = str_replace("/$requested_file","",$requested_uri); // get the directories only
228 $directories = substr($directories,1); // clean the string
229
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
230 if (!is_dir("$document_root/$cache_path/$resolution/$directories")) { // does the directory exist already?
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
231 if (!mkdir("$document_root/$cache_path/$resolution/$directories", 0777, true)) { // make the directory
232 // uh-oh, failed to make that directory
233 ImageDestroy($src); // clean-up after ourselves
234 ImageDestroy($dst); // clean-up after ourselves
235
236 /* notify the client by way of throwing a message in a bottle, as that's all we can do */
237 $im = ImageCreateTrueColor(800, 200);
238 $text_color = ImageColorAllocate($im, 233, 14, 91);
239 ImageString($im, 1, 5, 5, "Failed to create directories: $document_root/$cache_path/$resolution/$directories", $text_color);
240 header("Pragma: public");
241 header("Cache-Control: maxage=".$browser_cache);
242 header('Expires: '.gmdate('D, d M Y H:i:s', time()+$browser_cache).' GMT');
243 header('Content-Type: image/jpeg');
244 ImageJpeg($im); ImageDestroy($im);
245 exit();
246 }
247 }
248
249 // save the new file in the appropriate path, and send a version to the browser
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
250 switch ($extension) {
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
251 case png:
252 $gotSaved = ImagePng($dst, "$document_root/$cache_path/$resolution/$directories/$requested_file");
253 break;
254 case gif:
255 $gotSaved = ImageGif($dst, "$document_root/$cache_path/$resolution/$directories/$requested_file");
256 break;
257 default:
258 $gotSaved = ImageJpeg($dst, "$document_root/$cache_path/$resolution/$directories/$requested_file", $jpg_quality);
259 break;
260 }
261
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
262 if (!$gotSaved) {
69c53b5 @MattWilcox Impelemented a Mobile First approach
MattWilcox authored
263 /* Couldn't save image, notify the client by way of throwing a message in a bottle, as that's all we can do */
264 $im = ImageCreateTrueColor(800, 200);
265 $text_color = ImageColorAllocate($im, 233, 14, 91);
266 ImageString($im, 1, 5, 5, "Failed to create directories: $document_root/$cache_path/$resolution/$directories", $text_color);
267 header('Content-Type: image/jpeg');
268 ImageJpeg($im); ImageDestroy($im);
269 exit();
270 }
271 else { // we saved the image to cache, now deliver the image to the client
272 ImageDestroy($src); ImageDestroy($dst);
273 sendImage("$document_root/$cache_path/$resolution/$directories/$requested_file",$mime_type,$browser_cache);
274 }
275 }
276 } // end of if watch-cache
277 } // end it doesn't exist at the mobile size cached
278 }
ead2645 @MattWilcox Initial Commit
MattWilcox authored
279 }
280
281 $client_width = $_COOKIE["resolution"]; // store the cookie value in a variable
282
283 /* check the cookie value makes sense */
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
284 if (!is_numeric($client_width)) { // nope, that's not a numeric value
ead2645 @MattWilcox Initial Commit
MattWilcox authored
285 setcookie("resolution", "", time() -1); // delete the mangled cookie
286
287 /* now check to see if the requested file exists */
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
288 if (!file_exists($document_root.$requested_uri)) { // the requested file doesn't exist
ead2645 @MattWilcox Initial Commit
MattWilcox authored
289 header("Status: 404 Not Found");
290 exit();
291 }
292
293 // cookie was mangled so we don't know the client width, but the requested original image exists. Serve that.
294 sendImage($document_root.$requested_uri,$mime_type,$browser_cache);
295 }
296
297 /* the client width in the cookie is valid, now fit that number into the correct resolution break point */
298 rsort($resolutions); // make sure the supplied break-points are in reverse size order
299 $resolution = $resolutions[0]; // by default it's the largest supported break-point
300
301 foreach ($resolutions as $break_point) { // filter down
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
302 if ($client_width <= $break_point) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
303 $resolution = $break_point;
304 }
305 }
306
307 /* Use the resolution value as a path variable and check to see if an image of the same name exists at that path */
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
308 if (file_exists($document_root."/$cache_path/$resolution/".$requested_uri)) { // it exists cached at that size
ead2645 @MattWilcox Initial Commit
MattWilcox authored
309
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
310 if ($watch_cache) { // if cache watching is enabled, compare cache and source modified dates to ensure the cache isn't stale
ead2645 @MattWilcox Initial Commit
MattWilcox authored
311 $cache_date = filemtime($document_root."/".$cache_path."/".$resolution."/".$requested_uri);
312 $source_date = filemtime($document_root.$requested_uri);
313
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
314 if ($cache_date < $source_date) { // the source file has been replaced since the cache was generated
ead2645 @MattWilcox Initial Commit
MattWilcox authored
315 // Check the image dimensions
316 $source_image = $document_root.$requested_uri;
317 $dimensions = GetImageSize($source_image);
318 $width = $dimensions[0];
319 $height = $dimensions[1];
320
321 // Do we need to downscale the image?
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
322 if ($width <= $resolution) { // no, because the width of the source image is already less than the client width
ead2645 @MattWilcox Initial Commit
MattWilcox authored
323 sendImage($document_root.$requested_uri);
324 }
325
326 // We need to resize the source image to the width of the resolution breakpoint we're working with
327 $ratio = $height/$width;
328 $new_width = $resolution;
329 $new_height = ceil($new_width * $ratio);
330
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
331 switch ($extension) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
332 case png:
333 $src = @ImageCreateFromPng($source_image); // original image
334 break;
335 case gif:
336 $src = @ImageCreateFromGif($source_image); // original image
337 break;
338 default:
339 $src = @ImageCreateFromJpeg($source_image); // original image
340 break;
341 }
342
343 $dst = ImageCreateTrueColor($new_width,$new_height); // re-sized image
344 ImageCopyResampled($dst, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height); // do the resize in memory
345
346 // sharpen the image?
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
347 if ($sharpen == TRUE) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
348 $intSharpness = findSharp($width, $new_width);
349 $arrMatrix = array(
350 array(-1, -2, -1),
351 array(-2, $intSharpness + 12, -2),
352 array(-1, -2, -1)
353 );
354 imageconvolution($dst, $arrMatrix, $intSharpness, 0);
355 }
356
357 // check the path directory exists and is writable
358 $directories = str_replace("/$requested_file","",$requested_uri); // get the directories only
359 $directories = substr($directories,1); // clean the string
360
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
361 if (!is_dir("$document_root/$cache_path/$resolution/$directories")) { // does the directory exist already?
ead2645 @MattWilcox Initial Commit
MattWilcox authored
362 if (!mkdir("$document_root/$cache_path/$resolution/$directories", 0777, true)) { // make the directory
363 // uh-oh, failed to make that directory
364 ImageDestroy($src); // clean-up after ourselves
365 ImageDestroy($dst); // clean-up after ourselves
366
367 /* notify the client by way of throwing a message in a bottle, as that's all we can do */
368 $im = ImageCreateTrueColor(800, 200);
369 $text_color = ImageColorAllocate($im, 233, 14, 91);
370 ImageString($im, 1, 5, 5, "Failed to create directories: $document_root/$cache_path/$resolution/$directories", $text_color);
371 header("Pragma: public");
372 header("Cache-Control: maxage=".$browser_cache);
373 header('Expires: '.gmdate('D, d M Y H:i:s', time()+$browser_cache).' GMT');
374 header('Content-Type: image/jpeg');
375 ImageJpeg($im); ImageDestroy($im);
376 exit();
377 }
378 }
379
380 // save the new file in the appropriate path, and send a version to the browser
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
381 switch ($extension) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
382 case png:
383 $gotSaved = ImagePng($dst, "$document_root/$cache_path/$resolution/$directories/$requested_file");
384 break;
385 case gif:
386 $gotSaved = ImageGif($dst, "$document_root/$cache_path/$resolution/$directories/$requested_file");
387 break;
388 default:
389 $gotSaved = ImageJpeg($dst, "$document_root/$cache_path/$resolution/$directories/$requested_file", $jpg_quality);
390 break;
391 }
392
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
393 if (!$gotSaved) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
394 /* Couldn't save image, notify the client by way of throwing a message in a bottle, as that's all we can do */
395 $im = ImageCreateTrueColor(800, 200);
396 $text_color = ImageColorAllocate($im, 233, 14, 91);
397 ImageString($im, 1, 5, 5, "Failed to create directories: $document_root/$cache_path/$resolution/$directories", $text_color);
398 header('Content-Type: image/jpeg');
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
399 ImageJpeg($im);
400 ImageDestroy($im);
ead2645 @MattWilcox Initial Commit
MattWilcox authored
401 exit();
402 }
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
403
404 // we saved the image to cache, now deliver the image to the client
405 ImageDestroy($src);
406 ImageDestroy($dst);
407 sendImage("$document_root/$cache_path/$resolution/$directories/$requested_file",$mime_type,$browser_cache);
ead2645 @MattWilcox Initial Commit
MattWilcox authored
408 }
409 } // end of if watch-cache
410
411 sendImage($document_root."/$cache_path/$resolution/".$requested_uri,$mime_type,$browser_cache);
412 }
413
414 /* It doesn't exist as a cached file, check the default image folder to see if it exists there */
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
415 if (!file_exists($document_root.$requested_uri)) { // the file doesn't exist at the original size either
ead2645 @MattWilcox Initial Commit
MattWilcox authored
416 header("Status: 404 Not Found");
417 exit();
418 }
419
420 /* It exists as a source file, so lets work with that: */
421
422 // Check the image dimensions
423 $source_image = $document_root.$requested_uri;
424 $dimensions = GetImageSize($source_image);
425 $width = $dimensions[0];
426 $height = $dimensions[1];
427
428 // Do we need to downscale the image?
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
429 if ($width <= $resolution) { // no, because the width of the source image is already less than the client width
ead2645 @MattWilcox Initial Commit
MattWilcox authored
430 sendImage($document_root.$requested_uri,$mime_type,$browser_cache);
431 }
432
433 // We need to resize the source image to the width of the resolution breakpoint we're working with
434 $ratio = $height/$width;
435 $new_width = $resolution;
436 $new_height = ceil($new_width * $ratio);
437
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
438 switch ($extension) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
439 case png:
440 $src = @ImageCreateFromPng($source_image); // original image
441 break;
442 case gif:
443 $src = @ImageCreateFromGif($source_image); // original image
444 break;
445 default:
446 $src = @ImageCreateFromJpeg($source_image); // original image
447 break;
448 }
449
450 $dst = ImageCreateTrueColor($new_width,$new_height); // re-sized image
451 ImageCopyResampled($dst, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height); // do the resize in memory
452
453 // sharpen the image?
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
454 if ($sharpen == TRUE) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
455 $intSharpness = findSharp($width, $new_width);
456 $arrMatrix = array(
457 array(-1, -2, -1),
458 array(-2, $intSharpness + 12, -2),
459 array(-1, -2, -1)
460 );
461 imageconvolution($dst, $arrMatrix, $intSharpness, 0);
462 }
463
464 // check the path directory exists and is writable
465 $directories = str_replace("/$requested_file","",$requested_uri); // get the directories only
466 $directories = substr($directories,1); // clean the string
467
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
468 if (!is_dir("$document_root/$cache_path/$resolution/$directories")) { // does the directory exist already?
ead2645 @MattWilcox Initial Commit
MattWilcox authored
469 if (!mkdir("$document_root/$cache_path/$resolution/$directories", 0777, true)) { // make the directory
470 // uh-oh, failed to make that directory
471 ImageDestroy($src); // clean-up after ourselves
472 ImageDestroy($dst); // clean-up after ourselves
473
474 /* notify the client by way of throwing a message in a bottle, as that's all we can do */
475 $im = ImageCreateTrueColor(800, 200);
476 $text_color = ImageColorAllocate($im, 233, 14, 91);
477 ImageString($im, 1, 5, 5, "Failed to create directories: $document_root/$cache_path/$resolution/$directories", $text_color);
478 header("Pragma: public");
479 header("Cache-Control: maxage=".$browser_cache);
480 header('Expires: '.gmdate('D, d M Y H:i:s', time()+$browser_cache).' GMT');
481 header('Content-Type: image/jpeg');
482 ImageJpeg($im); ImageDestroy($im);
483 exit();
484 }
485 }
486
487 // save the new file in the appropriate path, and send a version to the browser
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
488 switch ($extension) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
489 case png:
490 $gotSaved = ImagePng($dst, "$document_root/$cache_path/$resolution/$directories/$requested_file");
491 break;
492 case gif:
493 $gotSaved = ImageGif($dst, "$document_root/$cache_path/$resolution/$directories/$requested_file");
494 break;
495 default:
496 $gotSaved = ImageJpeg($dst, "$document_root/$cache_path/$resolution/$directories/$requested_file", $jpg_quality);
497 break;
498 }
499
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
500 if (!$gotSaved) {
ead2645 @MattWilcox Initial Commit
MattWilcox authored
501 /* Couldn't save image, notify the client by way of throwing a message in a bottle, as that's all we can do */
502 $im = ImageCreateTrueColor(800, 200);
503 $text_color = ImageColorAllocate($im, 233, 14, 91);
504 ImageString($im, 1, 5, 5, "Failed to create directories: $document_root/$cache_path/$resolution/$directories", $text_color);
505 header('Content-Type: image/jpeg');
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
506 ImageJpeg($im);
507 ImageDestroy($im);
ead2645 @MattWilcox Initial Commit
MattWilcox authored
508 exit();
509 }
3569fa0 @Seldaek Whitespace/formatting fixes
Seldaek authored
510
511 // we saved the image to cache, now deliver the image to the client
512 ImageDestroy($src);
513 ImageDestroy($dst);
514 sendImage("$document_root/$cache_path/$resolution/$directories/$requested_file",$mime_type,$browser_cache);
Something went wrong with that request. Please try again.