. // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Find the Base path $script_location = $_SERVER['SCRIPT_FILENAME']; $script_location = substr($script_location, 0, strpos($script_location, 'wp-content')); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Options (you can tweak these) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// $opts = array( //////////////////////////////////////////////////////////////////////////////////////////////////////////////// // General (probably don't want to mess with these unless you know what you're doing) //////////////////////////////////////////////////////////////////////////////////////////////////////////////// 'cacheDirName' => 'resizurr_cache', // Cache directory name 'cacheDirLocation' => $script_location . '/wp-content', // Cache directory location (NULL = current directory) 'cacheDirLocationURL' => '/wp-content', // Cache directory location URL (NULL = /) 'cacheLimit' => 30, // Cache limit (in MB) 'localOnly' => true, // Only resize images on your own site (default) 'localHosts' => array(''), // Additional domains to considered local 'showErrors' => true, // Show error messages (set this to true if something isn't working) //////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Resizing defaults (which you'll probably override with URL variables) //////////////////////////////////////////////////////////////////////////////////////////////////////////////// 'width' => 300, // Width 'height' => 300, // Height 'quality' => 75, // Quality 'mode' => 'swsh', // Resize mode (swsh, swch, shcw, cc) 'anchor' => 'center', // Anchor (left, right, top, bottom, center) ); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // And you probably shouldn't edit anything below this line (unless you know what you're doing) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// try { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Quick checks //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (extension_loaded('gd') === false) throw new Exception('Resizurr requires the GD extension. Check with your web host.'); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Figure out cacheDir //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Figure out cacheDirLocation if ($opts['cacheDirLocation'] === NULL) $opts['cacheDirLocation'] = '.'; // Figure out cacheDirLocationURL if ($opts['cacheDirLocationURL'] === NULL) $opts['cacheDirLocationURL'] = '/'; // Check cacheDir $cacheDir = $opts['cacheDirLocation'] . '/' . $opts['cacheDirName'] . '/'; $cacheDirURL = $opts['cacheDirLocationURL'] . '/' . $opts['cacheDirName'] . '/'; if (file_exists($cacheDir) === false) { if (@mkdir($cacheDir) === false) throw new Exception('Could not create cache directory.'); if (@chmod($cacheDir, 0777) === false) throw new Exception('Could not set mode on cache directory.'); } else { if (is_readable($cacheDir) === false) throw new Exception('Cache dir isn\'t readable.'); if (is_writable($cacheDir) === false) throw new Exception('Cache dir isn\'t writable.'); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Get src //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (isset($_GET['src']) === false) throw new Exception('Missing src.'); $src = $_GET['src']; if (filter_var($src, FILTER_VALIDATE_URL) === false) throw new Exception('Invalid src. Must be a valid URL.'); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Get overrideable options //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Width if (isset($_GET['w']) === true) $opts['width'] = intval($_GET['w']); if (filter_var($opts['width'], FILTER_VALIDATE_INT) === false || $opts['width'] <= 0) throw new Exception('Invalid output width.'); // Height if (isset($_GET['h']) === true) $opts['height'] = intval($_GET['h']); if (filter_var($opts['height'], FILTER_VALIDATE_INT) === false || $opts['height'] <= 0) throw new Exception('Invalid output height.'); // Mode if (isset($_GET['m']) == true) $opts['mode'] = $_GET['m']; switch ($opts['mode']) { case 'swch': case 'cc': case 'swsh': case 'shcw': break; default: throw new Exception('Invalid mode. Must be swch, cc, swsh, or shcw.'); } // Anchor if (isset($_GET['a']) == true) $opts['anchor'] = $_GET['a']; switch ($opts['anchor']) { case 'left': case 'right': case 'top': case 'bottom': case 'center': break; default: throw new Exception('Invalid anchor. Must be left, right, top, bottom, or center.'); } // Height if (isset($_GET['q']) === true) $opts['quality'] = intval($_GET['q']); if ($opts['quality'] < 1 || $opts['quality'] > 100) throw new Exception('Invalid quality.'); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Build filename //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// $a = array( $opts['width'], $opts['height'], $opts['quality'], $opts['mode'], $opts['anchor'], $src ); if (function_exists('hash') === true) $filename = hash('sha512', implode('|', $a)) . '.jpg'; else $filename = md5(implode('|', $a)) . '.jpg'; $outputFilename = $cacheDir . $filename; $outputURL = $cacheDirURL . $filename; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Resize image (if it isn't cached) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (file_exists($outputFilename) === false) { // Get image data if ($opts['localOnly'] === true) { $a = parse_url($src); if ($a === false) throw new Exception('Couldn\'t parse the src URL. Hrm.'); $opts['localHosts'][] = $_SERVER['HTTP_HOST']; if (in_array($a['host'], $opts['localHosts']) === false) throw new Exception('Not allowed. Turn off localOnly and enable fopen wrappers in your server\'s PHP configuration.'); $xx = explode('/', $a['path']); foreach ($xx as $x) { $x = trim($x); if (substr($x, 0, 1) == '.') throw new Exception('Invalid src URL path.'); } $src = $script_location . $a['path']; } else { throw new Exception('Woops! Non-local images aren\'t supported yet! This will show up at some point though.'); } // Build image object $info = getimagesize($src); if ($info === false) throw new Exception('Couldn\'t determine the source image type.'); switch ($info[2]) { case IMAGETYPE_GIF: $srcImage = imagecreatefromgif($src); break; case IMAGETYPE_JPEG: $srcImage = imagecreatefromjpeg($src); break; case IMAGETYPE_PNG: $srcImage = imagecreatefrompng($src); break; default: throw new Exception('Not a supported src image type.'); } // Resize switch ($opts['mode']) { case 'swch': // Scale width, crop height // Destination $dX = 0; $dY = 0; $dW = $opts['width']; $dH = $opts['height']; // Source $sX = 0; $sY = 0; $sW = $info[0]; $sH = $info[1]; // Calculate $f = $sW / $dW; $sH = ceil($dH * $f); if ($opts['anchor'] == 'center' && $sH < $info[1]) { $sY = floor(($info[1] - $sH) / 2); $sX = floor(($info[0] - $sW) / 2); } else if ($opts['anchor'] == 'top') { $sX = floor(($info[0] - $sW) / 2); $sY = 0; } else if ($opts['anchor'] == 'bottom') { $sY = floor($info[1] - $sH); $sX = 0; } // Build output image $outputImage = imagecreatetruecolor($dW, $dH); // Resize imagecopyresampled( $outputImage, $srcImage, $dX, $dY, $sX, $sY, $dW, $dH, $sW, $sH ); break; case 'cc': // Crop from center // Destination $dX = 0; $dY = 0; $dW = $opts['width']; $dH = $opts['height']; // Source $sX = 0; $sY = 0; $sW = $info[0]; $sH = $info[1]; // Calculate $sX = ceil(($sW - $dW) / 2); $sY = ceil(($sH - $dH) / 2); // Build output image $outputImage = imagecreatetruecolor($dW, $dH); // Resize imagecopyresampled( $outputImage, $srcImage, $dX, $dY, $sX, $sY, $dW, $dH, $dW, $dH ); break; case 'swsh': // Scale width, scale height // Destination $dX = 0; $dY = 0; $dW = $opts['width']; $dH = $opts['height']; // Source $sX = 0; $sY = 0; $sW = $info[0]; $sH = $info[1]; // Calculate if ($sW > $dW || $sH > $dH) { $mW = $dW / $sW; $mH = $dH / $sH; $m = min($mW, $mH); $dW = floor($m * $sW); $dH = floor($m * $sH); } // Build output image $outputImage = imagecreatetruecolor($dW, $dH); // Resize imagecopyresampled( $outputImage, $srcImage, $dX, $dY, $sX, $sY, $dW, $dH, $sW, $sH ); break; case 'shcw': // Scale height, crop width // Destination $dX = 0; $dY = 0; $dW = $opts['width']; $dH = $opts['height']; // Source $sX = 0; $sY = 0; $sW = $info[0]; $sH = $info[1]; // Calculate $f = $sH / $dH; $sW = ceil($dW * $f); if ($opts['anchor'] == 'center') { $sY = floor(($info[1] - $sH) / 2); $sX = floor(($info[0] - $sW) / 2); } else if ($opts['anchor'] == 'left') { $sX = 0; $sY = 0; } else if ($opts['anchor'] == 'right') { $sX = ($info[0] - $sW); $sY = 0; } // Build output image $outputImage = imagecreatetruecolor($dW, $dH); // Resize imagecopyresampled( $outputImage, $srcImage, $dX, $dY, $sX, $sY, $dW, $dH, $sW, $sH ); break; default: throw new Exception('Shouldn\'t be here!'); } // Save it imagejpeg($outputImage, $outputFilename, $opts['quality']); @chmod($outputFilename, 0666); // Prune cache // Build file list $fileSizes = array(); $fileDates = array(); $dh = opendir($cacheDir); $total = 0; while (($filename = readdir($dh)) !== false) { $fullFilename = $cacheDir . $filename; if (is_dir($fullFilename) === true) continue; $fileSizes[$filename] = filesize($fullFilename); $fileDates[$filename] = filemtime($fullFilename); $total += $fileSizes[$filename]; } // Sort by date asort($fileDates); // Delete oldest $limit = $opts['cacheLimit'] * 1048576; if ($total > $limit) { // Pad out the total (to prevent thrashing) $total += (($total / count($fileDates)) * 5); $filenames = array_keys($fileDates); $i = 0; while ($total > $limit && isset($filenames[$i]) === true) { $fullFilename = $cacheDir . $filenames[$i]; @unlink($fullFilename); $total -= $fileSizes[$filenames[$i]]; $i++; } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Output cached image //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (file_exists($outputFilename) === false || is_readable($outputFilename) === false) throw new Exception('Could not access cached image.'); header('Location: ' . $outputURL); } catch (Exception $e) { if ($opts['showErrors'] === true) echo 'Error: ' . $e->getMessage(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // EOF. See you around. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ?>