/imageserver.php
PHP | 519 lines | 373 code | 90 blank | 56 comment | 59 complexity | 670bdbd6eee96a3231b782a567dcbcaa MD5 | raw file
- <?php
- include 'imageserver.config.php';
- if (URI_PROTOCOL == 'REQUEST_URI')
- {
- $filename = $_SERVER['REQUEST_URI'];
- if (isset($_SERVER['QUERY_STRING']))
- {
- $filename = str_replace("?$_SERVER[QUERY_STRING]", '', $filename);
- }
- }
- else
- {
- $filename = isset($_SERVER['REDIRECT_URL']) ? $_SERVER['REDIRECT_URL'] : NULL;
- }
- if ( ! $filename)
- {
- exit;
- }
- $filename = DIR_RELATIVE . str_replace(SCRIPT_RELATIVE .'imgs/', '', $filename);
- $filename = urldecode($filename);
- if ( ! file_exists($filename))
- {
- //The source image can't be found, so use a default, if it is set
- if (defined('REPLACEMENT_IMG') AND file_exists(DIR_RELATIVE.REPLACEMENT_IMG))
- {
- $location = "http://$_SERVER[HTTP_HOST]". SCRIPT_RELATIVE .'imgs/'. REPLACEMENT_IMG;
-
- if ($_SERVER['QUERY_STRING'])
- {
- $location .= "?$_SERVER[QUERY_STRING]";
- }
-
- imgs_log("File $filename not found, 301 redirect to: $location");
-
- header("Location: $location", TRUE, 307);
- }
- else
- {
- imgs_log("File '$filename' not found");
- }
-
- exit;
- }
- if (CACHE_EXPIRES)
- {
- $exp_time = strtotime(CACHE_EXPIRES);
- header('Expires: ' . date(DATE_RFC2822, $exp_time));
- header('Pragma: cache');
- $seconds = $exp_time - time();
- header("Cache-Control: public, max-age=$seconds, pre-check=$seconds");
- }
- list($orig_width, $orig_height, $type) = getimagesize($filename);
- $width = 0;
- $height = 0;
- /*
- * Fetch user defined parameters
- */
- if (isset($_GET['w']) AND is_numeric($_GET['w']))
- {
- $width = intval($_GET['w']);
- }
- if (isset($_GET['h']) AND is_numeric($_GET['h']))
- {
- $height = intval($_GET['h']);
- }
- $should_watermark = FALSE;
- // If resizing was not requested, but the image is larger than the minimum for watermarking
- if (WATERMARK AND ! $width AND ! $height AND ($orig_width >= WATERMARK_MINW OR $orig_height >= WATERMARK_MINH))
- {
- $width = $orig_width;
- $height = $orig_height;
- $should_watermark = TRUE;
- }
- elseif (WATERMARK AND (($width > WATERMARK_MINW OR $height > WATERMARK_MINH)))
- {
- $should_watermark = TRUE;
- }
- // If the requested file is the original, non-processed image
- if ( ! $width AND ! $height AND ! $should_watermark)
- {
- // If the file exists, just serve it and finish execution
- $details = getimagesize($filename);
- if ($details)
- {
- header('Content-Type: '. $details['mime']);
- echo file_get_contents($filename);
- exit();
- }
- }
- $should_fill = FALSE;
- $should_cut = FALSE;
- // If we have both width and height requested, we can fill or cut
- if ($width AND $height)
- {
- if ((isset($_GET['f']) AND $_GET['f'] == 1) OR BG_FILL)
- {
- $should_fill = TRUE;
- }
- else
- {
- // Should we cut the image to fill the requested dimensions?
- // -------------------------------------------------------------------------
- if (isset($_GET['c']))
- {
- if ($_GET['c'] == 1)
- {
- $should_cut = TRUE;
- }
- }
- elseif (CUTTING)
- {
- $should_cut = TRUE;
- }
- }
- }
- $pi = pathinfo($filename);
- $target_dir = CACHE_RELATIVE."/{$pi['dirname']}";
- $bg_tag = ($should_fill ? '_bg' : '');
- $wm_tag = ($should_watermark ? '_wm' : '');
- $ct_tag = ($should_cut ? '_c' : '');
- // Target file is a resized image
- $target_file = "{$target_dir}/{$pi['filename']}_{$width}_{$height}{$bg_tag}{$wm_tag}{$ct_tag}.{$pi['extension']}";
- // Has this request already been cached once upon a time?
- if (CACHE AND file_exists($target_file) AND (filectime($target_file) > filectime($filename)))
- {
- imgs_log("Serving from cache");
- $details = getimagesize($target_file);
- if ($details)
- {
- header('Content-Type: '. $details['mime']);
- echo file_get_contents($target_file);
- exit();
- }
- }
- else
- {
- // Original file exists and resize/resample action is needed
- // Does the target directory exist?
- if (CACHE AND ! is_dir($target_dir) AND ! mkdir($target_dir, 0775, TRUE))
- {
- // Directory not found and we were unable to create one...
- // TODO: handle target directory creation error
- exit();
- }
- $ratio = $orig_width/$orig_height;
- // If one of the dimensions was not specified, use the original scaled by the difference ratio
- // If cutting, this will have no effect (cutting requires both dimensions, so neither of these eval as TRUE)
- if ($width == 0)
- {
- $width = round($orig_width * ($height/$orig_height));
- }
- elseif ($height == 0)
- {
- $height = round($orig_height * ($width/$orig_width));
- }
- $resample_width = $width;
- $resample_height = $height;
- // Preserve aspect ratio
- if ($resample_width / $resample_height > $ratio)
- {
- $resample_width = round($resample_height * $ratio);
- }
- else
- {
- $resample_height = round($resample_width / $ratio);
- }
- $dst_x = 0;
- $dst_y = 0;
- $src_x = 0;
- $src_y = 0;
- if ($should_fill AND strlen(BG_RGB) == 7)
- {
- // If background filling is enabled, create an image with the requested dimension
- $new_image = imagecreatetruecolor($width, $height);
- // Fill the image with the specified colour
- $bg = sscanf(BG_RGB, '#%2x%2x%2x');
- $new_image_bg = imagecolorallocate($new_image, $bg[0], $bg[1], $bg[2]);
- imagefill($new_image, 0, 0, $new_image_bg);
- if ($width == $resample_width)
- {
- $dst_x = 0;
- }
- elseif ($width > $resample_width)
- {
- $dst_x = round(($width - $resample_width) / 2);
- }
- else
- {
- $dst_x = round(($resample_width - $width) / 2);
- }
- if ($height == $resample_height)
- {
- $dst_y = 0;
- }
- elseif ($height > $resample_height)
- {
- $dst_y = round(($height - $resample_height) / 2);
- }
- else
- {
- $dst_y = round(($resample_height - $height) / 2);
- }
- }
- elseif ($should_cut)
- {
- // Will cut, so the requested dimension will be respected
- $new_image = imagecreatetruecolor($width, $height);
- $target_ar = round($width/$height, 2);
- $ratio = round($ratio, 2);
- if ($orig_width == $orig_height) // ------------------------------------ Source is square
- {
- if ($width < $height)
- {
- // Target is portrait
- $resample_height = $height;
- $resample_width = round($resample_height * $ratio);
- $dst_x = - ceil(($resample_width - $width) / 2);
- }
- elseif ($width > $height)
- {
- // Target is landscape
- $resample_width = $width;
- $resample_height = round($resample_width / $ratio);
- $dst_y = - ceil(($resample_height - $height) / 2);
- }
- }
- elseif ($orig_width < $orig_height) // --------------------------------- Source is portrait
- {
- if ($width >= $height OR $target_ar > $ratio)
- {
- // Target is square or landscape or less narrow than the original
- $resample_width = $width;
- $resample_height = round($resample_width / $ratio);
- $dst_y = - ceil(($resample_height - $height) / 2);
- }
- elseif ($width < $height AND $target_ar < $ratio)
- {
- // Target is portrait or more narrow than the original
- $resample_height = $height;
- $resample_width = round($resample_height * $ratio);
- $dst_x = - ceil(($resample_width - $width) / 2);
- }
- }
- else // ---------------------------------------------------------------- Source is landscape
- {
- if ($width <= $height OR $target_ar < $ratio)
- {
- // Target is square or portrait or more narrow than the original
- $resample_height = $height;
- $resample_width = round($resample_height * $ratio);
- $dst_x = - ceil(($resample_width - $width) / 2);
- }
- elseif ($target_ar > $ratio)
- {
- // Target is landscape or less narrow than the original
- $resample_width = $width;
- $resample_height = round($resample_width / $ratio);
- $dst_y = - ceil(($resample_height - $height) / 2);
- }
- }
- }
- else
- {
- // No background filling or cutting, create an image with same ratio
- $new_image = imagecreatetruecolor($resample_width, $resample_height);
- }
- // Retain transparency, if any
- if ( ! $should_fill)
- {
- $trans_colour = imagecolorallocatealpha($new_image, 0, 0, 0, 127);
- imagefill($new_image, 0, 0, $trans_colour);
- imagesavealpha($new_image, TRUE);
- }
- // TODO: set padding if required
- imgs_log("imagecopyresampled($target_file, $filename, $dst_x, $dst_y, $src_x, $src_y, $resample_width, $resample_height, $orig_width, $orig_height)");
- switch ($type)
- {
- // ----
- case 1: // GIF
- // ----
- $image = imagecreatefromgif($filename);
- if ($image)
- {
- if (imagecopyresampled($new_image, $image, $dst_x, $dst_y, $src_x, $src_y, $resample_width, $resample_height, $orig_width, $orig_height))
- {
- if ($should_watermark)
- {
- imgs_apply_watermark($new_image);
- }
-
- // Save to cache
- if (CACHE)
- {
- imagegif($new_image, $target_file);
- //@chmod($target_file,PERMISSION);
- }
- // Output
- header('Content-type: image/gif');
- imagegif($new_image);
- }
- }
-
- break;
- // ----
- case 2: //JPEG
- // ----
- $image = imagecreatefromjpeg($filename);
- if ($image)
- {
- if (imagecopyresampled($new_image, $image, $dst_x, $dst_y, $src_x, $src_y, $resample_width, $resample_height, $orig_width, $orig_height))
- {
- if ($should_watermark)
- {
- imgs_apply_watermark($new_image);
- }
- // Save to cache
- if (CACHE)
- {
- imagejpeg($new_image, $target_file, JPEG_QUALITY);
- //@chmod($target_file,PERMISSION);
- }
- // Output
- header('Content-type: image/jpeg');
- imagejpeg($new_image, NULL, JPEG_QUALITY);
- }
- }
-
- break;
- // ----
- case 3: // PNG
- // ----
-
- $line = "Creating PNG: ";
- $image = imagecreatefrompng($filename);
-
- if ($image)
- {
- $line .= "OK";
- imgs_log($line);
- $line = "Resampling: ";
- if (imagecopyresampled($new_image, $image, $dst_x, $dst_y, $src_x, $src_y, $resample_width, $resample_height, $orig_width, $orig_height))
- {
- $line .= "OK";
-
- if ($should_watermark)
- {
- imgs_apply_watermark($new_image);
- }
-
- // Save to cache
- if (CACHE)
- {
- imagepng($new_image, $target_file, PNG_QUALITY);
- //@chmod($target_file,PERMISSION);
- }
-
- // Output
- header('Content-type: image/png');
- imagepng($new_image, NULL, PNG_QUALITY);
- }
- else
- {
- $line .= "FAILED";
- }
- }
- else
- {
- $line .= "FAILED";
- }
- imgs_log($line);
- } // -- end type switch
- }
- function imgs_log($line)
- {
- if ( ! DEBUG)
- {
- return;
- }
- if ( ! file_exists(LOG_PATH) OR ! is_writeable(LOG_PATH))
- {
- return;
- }
- $line = date("Y-m-d H:i:s") .": $line\n";
- file_put_contents(LOG_PATH, $line, FILE_APPEND | LOCK_EX);
- }
- /**
- * Apply the watermark to the image
- * @param resource $image
- * @param int $width
- * @param int $height
- * @return bool
- */
- function imgs_apply_watermark(&$image)
- {
- if (file_exists(WATERMARK))
- {
- $wm = imagecreatefrompng(WATERMARK);
- list($wm_width, $wm_height) = getimagesize(WATERMARK);
- $width = imagesx($image);
- $height = imagesy($image);
- // If we want resizing or the watermark is too big for this image
- if (WATERMARK_RESIZE OR $wm_width > $width OR $wm_height > $height)
- {
- $ratio = $wm_width/$wm_height;
- $new_wm_height = $height;
- $new_wm_width = $width;
- // Preserve aspect ratio of the watermark
- if ($new_wm_width/$new_wm_height > $ratio)
- {
- $new_wm_width = round($new_wm_height*$ratio);
- }
- else
- {
- $new_wm_height = round($new_wm_width/$ratio);
- }
- }
- else
- {
- $new_wm_height = $wm_height;
- $new_wm_width = $wm_width;
- }
- switch (WATERMARK_HALIGN)
- {
- case 'left': $dst_x = 0; break;
- case 'right': $dst_x = $width - $new_wm_width; break;
- default:
- case 'center': $dst_x = intval(($width - $new_wm_width) / 2);
- }
- switch (WATERMARK_VALIGN)
- {
- case 'top': $dst_y = 0; break;
- case 'bottom': $dst_y = $height - $new_wm_height; break;
- default:
- case 'center': $dst_y = intval(($height - $new_wm_height) / 2);
- }
- // Copy resampled watermark
- imagecopyresampled($image, $wm, $dst_x, $dst_y, 0, 0, $new_wm_width, $new_wm_height, $wm_width, $wm_height);
- return TRUE;
- }
- return FALSE;
- }