Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 21 additions & 48 deletions adaptive-images.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@

/* CONFIG ----------------------------------------------------------------------------------------------------------- */

$resolutions = array(1382, 992, 768, 480); // the resolution break-points to use (screen widths, in pixels)
$resolutions = array(2560,1920,1440,1024,768,480); // the resolution break-points to use (screen widths, in pixels)
$cache_path = "ai-cache"; // where to store the generated re-sized images. Specify from your document root!
$jpg_quality = 75; // the quality of any generated JPGs on a scale of 0 to 100
$sharpen = TRUE; // Shrinking images can blur details, perform a sharpen on re-scaled images?
$jpg_quality = 85; // the quality of any generated JPGs on a scale of 0 to 100
$sharpen = FALSE; // Shrinking images can blur details, perform a sharpen on re-scaled images?
$watch_cache = TRUE; // check that the adapted image isn't stale (ensures updated source images are re-cached)
$browser_cache = 60*60*24*7; // How long the BROWSER cache should last (seconds, minutes, hours, days. 7days by default)
$cookie_name = "ai-resolution";

/* END CONFIG ----------------------------------------------------------------------------------------------------------
------------------------ Don't edit anything after this line unless you know what you're doing -------------------------
Expand All @@ -30,7 +31,7 @@
$source_file = $document_root.$requested_uri;
$resolution = FALSE;

/* Mobile detection
/* Mobile detection
NOTE: only used in the event a cookie isn't available. */
function is_mobile() {
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
Expand All @@ -56,6 +57,7 @@ function is_mobile() {

/* helper function: Send headers and returns an image. */
function sendImage($filename, $browser_cache) {
//sendErrorImage($filename);
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (in_array($extension, array('png', 'gif', 'jpeg'))) {
header("Content-Type: image/".$extension);
Expand Down Expand Up @@ -170,7 +172,7 @@ function generateImage($source_file, $cache_file, $resolution) {
$transparent = imagecolorallocatealpha($dst, 255, 255, 255, 127);
imagefilledrectangle($dst, 0, 0, $new_width, $new_height, $transparent);
}

ImageCopyResampled($dst, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height); // do the resize in memory
ImageDestroy($src);

Expand All @@ -189,7 +191,7 @@ function generateImage($source_file, $cache_file, $resolution) {
$cache_dir = dirname($cache_file);

// does the directory exist already?
if (!is_dir($cache_dir)) {
if (!is_dir($cache_dir)) {
if (!mkdir($cache_dir, 0755, true)) {
// check again if it really doesn't exist to protect against race conditions
if (!is_dir($cache_dir)) {
Expand Down Expand Up @@ -241,54 +243,23 @@ function generateImage($source_file, $cache_file, $resolution) {
}

/* Check to see if a valid cookie exists */
if (isset($_COOKIE['resolution'])) {
$cookie_value = $_COOKIE['resolution'];

if (isset($_COOKIE[$cookie_name])) {
$cookie_value = $_COOKIE[$cookie_name];
// does the cookie look valid? [whole number, comma, potential floating number]
if (! preg_match("/^[0-9]+[,]*[0-9\.]+$/", "$cookie_value")) { // no it doesn't look valid
setcookie("resolution", "$cookie_value", time()-100); // delete the mangled cookie
setcookie($cookie_name, $cookie_value, time()-100); // delete the mangled cookie
}
else { // the cookie is valid, do stuff with it
$cookie_data = explode(",", $_COOKIE['resolution']);
$cookie_data = explode(",", $_COOKIE[$cookie_name]);
$client_width = (int) $cookie_data[0]; // the base resolution (CSS pixels)
$total_width = $client_width;
$pixel_density = 1; // set a default, used for non-retina style JS snippet
if (@$cookie_data[1]) { // the device's pixel density factor (physical pixels per CSS pixel)
$pixel_density = $cookie_data[1];
}

rsort($resolutions); // make sure the supplied break-points are in reverse size order
$resolution = $resolutions[0]; // by default use the largest supported break-point

// if pixel density is not 1, then we need to be smart about adapting and fitting into the defined breakpoints
if($pixel_density != 1) {
$total_width = $client_width * $pixel_density; // required physical pixel width of the image

// the required image width is bigger than any existing value in $resolutions
if($total_width > $resolutions[0]){
// firstly, fit the CSS size into a break point ignoring the multiplier
foreach ($resolutions as $break_point) { // filter down
if ($total_width <= $break_point) {
$resolution = $break_point;
}
}
// now apply the multiplier
$resolution = $resolution * $pixel_density;
}
// the required image fits into the existing breakpoints in $resolutions
else {
foreach ($resolutions as $break_point) { // filter down
if ($total_width <= $break_point) {
$resolution = $break_point;
}
}
}
}
else { // pixel density is 1, just fit it into one of the breakpoints
foreach ($resolutions as $break_point) { // filter down
if ($total_width <= $break_point) {
$resolution = $break_point;
}
$total_width = $client_width * $pixel_density;
foreach ($resolutions as $test_resolution) { // filter down
if ($test_resolution >= $total_width) {
$resolution = $test_resolution;
}
}
}
Expand All @@ -305,18 +276,20 @@ function generateImage($source_file, $cache_file, $resolution) {
$requested_uri = substr($requested_uri, 1);
}

$resolution = floor($resolution);

/* whew might the cache file be? */
$cache_file = $document_root."/$cache_path/$resolution/".$requested_uri;
//$cache_file = $document_root."/$cache_path/$resolution/".$requested_uri;
$cache_file = $document_root."/$cache_path/$resolution/".hash("md5", $requested_uri);

/* Use the resolution value as a path variable and check to see if an image of the same name exists at that path */
if (file_exists($cache_file)) { // it exists cached at that size
if ($watch_cache) { // if cache watching is enabled, compare cache and source modified dates to ensure the cache isn't stale
$cache_file = refreshCache($source_file, $cache_file, $resolution);
}

sendImage($cache_file, $browser_cache);
}

/* It exists as a source file, and it doesn't exist cached - lets make one: */
$file = generateImage($source_file, $cache_file, $resolution);
sendImage($file, $browser_cache);
sendImage($file, $browser_cache);