diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.htaccess b/.htaccess deleted file mode 100644 index 19be14d..0000000 --- a/.htaccess +++ /dev/null @@ -1,22 +0,0 @@ - - Options +FollowSymlinks - RewriteEngine On - - # Adaptive-Images ----------------------------------------------------------------------------------- - - # Add any directories you wish to omit from the Adaptive-Images process on a new line, as follows: - # RewriteCond %{REQUEST_URI} !ignore-this-directory - # RewriteCond %{REQUEST_URI} !and-ignore-this-directory-too - - RewriteCond %{REQUEST_URI} !assets - - # don't apply the AI behaviour to images inside AI's cache folder: - RewriteCond %{REQUEST_URI} !ai-cache - - # Send any GIF, JPG, or PNG request that IS NOT stored inside one of the above directories - # to adaptive-images.php so we can select appropriately sized versions - - RewriteRule \.(?:jpe?g|gif|png)$ adaptive-images.php - - # END Adaptive-Images ------------------------------------------------------------------------------- - \ No newline at end of file diff --git a/adaptive-images.php b/adaptive-images.php deleted file mode 100755 index 1d51420..0000000 --- a/adaptive-images.php +++ /dev/null @@ -1,322 +0,0 @@ -= filemtime($source_file)) { - return $cache_file; - } - - // modified, clear it - unlink($cache_file); - } - return generateImage($source_file, $cache_file, $resolution); -} - -/* generates the given cache file for the given source file with the given resolution */ -function generateImage($source_file, $cache_file, $resolution) { - global $sharpen, $jpg_quality; - - $extension = strtolower(pathinfo($source_file, PATHINFO_EXTENSION)); - - // Check the image dimensions - $dimensions = GetImageSize($source_file); - $width = $dimensions[0]; - $height = $dimensions[1]; - - // Do we need to downscale the image? - if ($width <= $resolution) { // no, because the width of the source image is already less than the client width - return $source_file; - } - - // We need to resize the source image to the width of the resolution breakpoint we're working with - $ratio = $height/$width; - $new_width = $resolution; - $new_height = ceil($new_width * $ratio); - $dst = ImageCreateTrueColor($new_width, $new_height); // re-sized image - - switch ($extension) { - case 'png': - $src = @ImageCreateFromPng($source_file); // original image - break; - case 'gif': - $src = @ImageCreateFromGif($source_file); // original image - break; - default: - $src = @ImageCreateFromJpeg($source_file); // original image - ImageInterlace($dst, true); // Enable interlancing (progressive JPG, smaller size file) - break; - } - - if($extension=='png'){ - imagealphablending($dst, false); - imagesavealpha($dst,true); - $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); - - // sharpen the image? - // NOTE: requires PHP compiled with the bundled version of GD (see http://php.net/manual/en/function.imageconvolution.php) - if($sharpen == TRUE && function_exists('imageconvolution')) { - $intSharpness = findSharp($width, $new_width); - $arrMatrix = array( - array(-1, -2, -1), - array(-2, $intSharpness + 12, -2), - array(-1, -2, -1) - ); - imageconvolution($dst, $arrMatrix, $intSharpness, 0); - } - - $cache_dir = dirname($cache_file); - - // does the directory exist already? - 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)) { - // uh-oh, failed to make that directory - ImageDestroy($dst); - sendErrorImage("Failed to create cache directory: $cache_dir"); - } - } - } - - if (!is_writable($cache_dir)) { - sendErrorImage("The cache directory is not writable: $cache_dir"); - } - - // save the new file in the appropriate path, and send a version to the browser - switch ($extension) { - case 'png': - $gotSaved = ImagePng($dst, $cache_file); - break; - case 'gif': - $gotSaved = ImageGif($dst, $cache_file); - break; - default: - $gotSaved = ImageJpeg($dst, $cache_file, $jpg_quality); - break; - } - ImageDestroy($dst); - - if (!$gotSaved && !file_exists($cache_file)) { - sendErrorImage("Failed to create image: $cache_file"); - } - - return $cache_file; -} - -// check if the file exists at all -if (!file_exists($source_file)) { - header("Status: 404 Not Found"); - exit(); -} - -/* check that PHP has the GD library available to use for image re-sizing */ -if (!extension_loaded('gd')) { // it's not loaded - if (!function_exists('dl') || !dl('gd.so')) { // and we can't load it either - // no GD available, so deliver the image straight up - trigger_error('You must enable the GD extension to make use of Adaptive Images', E_USER_WARNING); - sendImage($source_file, $browser_cache); - } -} - -/* Check to see if a valid cookie exists */ -if (isset($_COOKIE['resolution'])) { - $cookie_value = $_COOKIE['resolution']; - - // 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 - } - else { // the cookie is valid, do stuff with it - $cookie_data = explode(",", $_COOKIE['resolution']); - $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; - } - } - } - } -} - -/* No resolution was found (no cookie or invalid cookie) */ -if (!$resolution) { - // We send the lowest resolution for mobile-first approach, and highest otherwise - $resolution = $is_mobile ? min($resolutions) : max($resolutions); -} - -/* if the requested URL starts with a slash, remove the slash */ -if(substr($requested_uri, 0,1) == "/") { - $requested_uri = substr($requested_uri, 1); -} - -/* whew might the cache file be? */ -$cache_file = $document_root."/$cache_path/$resolution/".$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); \ No newline at end of file diff --git a/ai-cookie-snippet.js b/ai-cookie-snippet.js new file mode 100644 index 0000000..cc16b9b --- /dev/null +++ b/ai-cookie-snippet.js @@ -0,0 +1,107 @@ +/* + * + * The über-extended version of device width detection and cookie setting + * More robust and reliable on newer and future mobile devices with accompanied browsers + * + * Uses original screen.width method as a fallback + * Progressive enhances using media queries through mediaMatch if available + * Runs only on first visit, when our cookie is not yet present + * + */ + + +// Perform test if cookie is already present +var cookie = (readCookie('resolution') ? true : false ); + +// Only do stuff when neccesary! +// Remember: in case a corrupted cookie is once set, Adaptive Images will erase it later in php +// So we always have a second chance +if (!cookie) { + + +// Use original strategy as a "fallback" now +// For older browsers/devices, this will usually return valid values +// We set this FIRST because it seems faster to do +document.cookie = 'resolution=' + + Math.max( screen.width, screen.height ) +// + ( "devicePixelRatio" in window ? "," + devicePixelRatio : ",1") // Better to leave out device pixel ratio in the fallback + + ",1" + + '; path=/'; + + + +// Progressive enhance if available +// Use sophisicated and more reliable strategy to determine device width via media queries +// For newer and future browsers this will be no problem +// Http://caniuse.com/#feat=matchmedia +if (window.matchMedia) { + + // Instantiate the variable for resolution + var resolution = null; + + + // Loop through plausible possibilities of screen resolutions + // Make sure all used values are multiples of 8! + for ( var i=240; i<=4088; i=i+8 ) { + + // Build our media query strings for assessing width and height + width = '(max-device-width: ' + i + 'px)'; + height = '(max-device-height: ' + i + 'px)'; + + // Test if and when both of the maximum dimensions of the devices screen are met + // Inspired by: http://stackoverflow.com/questions/6850164/get-the-device-width-in-javascript + if ( (window.matchMedia( width ).matches == true) && (window.matchMedia( height ).matches == true) ) + { break; } + } + + + // Assing found resolution "late" (= after and outside of the for-loop) + // In case the if-statement doesn’t break the for-loop – means that screen size exceeds max value of for-loop + // This way, we do catch at least the biggest value from the for-loop + // It’s like a "fallback" with a built-in "limiter" + // Feel free to tailor to your needst he max value of the for-loop above (in multiples of 8!) + resolution = i; + + + // In case something useful was detected: set our sophisticated cookie + if ( (resolution) && (resolution != "") && (typeof resolution === 'number') && (resolution % 1 === 0) ) { + + document.cookie = 'resolution=' + + resolution + + ( 'devicePixelRatio' in window ? ',' + devicePixelRatio : ',1') + + '; path=/'; + } + else { + // Otherwise rely on our fallback AGAIN! + // Looks like redundancy, but is actually necessary to be more safe and robust + // Imagine the sophisticated version above returns crap or null and then sets this as a cookie ... + document.cookie = 'resolution=' + + Math.max( screen.width, screen.height ) +// + ( "devicePixelRatio" in window ? "," + devicePixelRatio : ",1") // Let’s leave out device pixel ratio in the fallback + + ",1" + + '; path=/'; + + } + +} // End of: sophisticated media query version + +} // End of: is a cookie set? + + + + +// Helper function; credits: ppk, quirksmode.org +// Returns cookie value(s) +// We use it just to see if a cookie is present +function readCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for(var i=0;i < ca.length;i++) { + var c = ca[i]; + while (c.charAt(0)==' ') c = c.substring(1,c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); + } + return null; +} + + diff --git a/ai-cookie.php b/ai-cookie.php deleted file mode 100644 index 4b65d03..0000000 --- a/ai-cookie.php +++ /dev/null @@ -1,9 +0,0 @@ -. That is now fixed. If AI detects retina displays it - is now able to generate larger images than the top bounds set in $resolutions. - -version 1.5.1 (2012/04/14) ------------------------------------------------------------ - - ENHANCEMENT - * JPGs are now created as Progressive rather than Optimised. - - Progressive JPGs are actually slightly smaller in file-size than Optimised JPGs, - and have the benefit of appearing to load faster in modern browsers (they - download in passes, gradually getting sharper). - -version 1.5 (2012/04/14) -------------------------------------------------------------- - - ENHANCEMENT - * Much improved support for Retina and other high DPI devices - - NOTE: Retina support requires using alternate JavaScript: - - - NOTE: If you see folders in the ai-cache directory which are *larger* than any - defined in your $resolutions array, it is because someone with a high DPI / Retina - display visited your site, and AI was able to generate the required image for them. - - DETAILS: - Previous AI behaviour meant that supporting Retina required adding very high values - in the $resolutions array. This is sub-optimal because: - - 1) This array is meant to be nothing more than the same values as your media query - breakpoints. Adding larger ones isn't intuitive. - 2) When no cookie is set, AI sends non-mobile devices the largest $resolution value, - which in that case could be far too large for most people (2000px+) - - AI is now much smarter, you do not need to edit the $resolutions array; just leave - that as your CSS MQ sizes. - - AI now auto-detects the pixel density of any high DPI device and either picks a - matching size from the existing array, or creates new high-dpi images which are - multiples of your chosen $resolutions values. - -version 1.4.1 (2012/03/28) ------------------------------------------------------------ - - ENHANCEMENT - * More helpful error messages if something goes wrong. - * Updated the documentation a little. - -version 1.4 (2012/02/19) -------------------------------------------------------------- - - ENHANCEMENT - * Auto-creates the cache folder with the correct permissions. - No need to manually create the ai-cache folder any more, AI does it for you. - - BUG FIX - * Fixed an incorrect permission on created files, they're now 755 not 777. - -version 1.3.9 (2012/02/17) ------------------------------------------------------------ - Thanks to Gerv - - ENHANCEMENT - * Better detection of mobile device in the event cookies are not available. - - If cookies are unavailable AI resorts to basic UA sniffing. - - Previously AI assumed all devices are mobile and searched the UA string for a - desktop OS. If found it overrode $mobile_first. However, this meant tablet - devices got mobile sized images as their OS is not a desktop OS. - - Now switched to assume the device is a desktop, but AI searches the UA string for - 'mobile' to switch to mobile first. All current mobile browsers behave in this - way, meaning mobiles still get mobile resolution, but tablets and desktop get - the largest configured resolution. - - * Removed $mobile_first as it is no longer needed (see above) - -version 1.3.8 (2012/01/24) ------------------------------------------------------------ - - BUG FIX - * Eliminated occasional double-slash in $cache_file path due to $requested_uri - sometimes starting with a / - -version 1.3.7 (2011/11/21) ------------------------------------------------------------ - - BUG FIX - * A stupid mistake was causing the browser detect to always return false. - This has been fixed. - - With this update Adaptive Images now detects if a user is running on a desktop OS - and switches $mobile_first to FALSE in that case. This means that if no cookie is - set and $mobile_first is TRUE the following will happen: - - On a mobile phone, the mobile sized image will be delivered. - On a desktop, the highest resolution configured will be delivered. - - If a cookie is set, Adaptive Images will use the cookie value to determine the - correct size image to send. - -version 1.3.6 (2011/11/11) ------------------------------------------------------------ - - NOTES - * Added Linux desktop detection to the $mobile_first check routine (see previous - changelog details) - -version 1.3.5 (2011/11/10) ------------------------------------------------------------ - - NEW FEATURE - * To work around browser issues with unreliable cookie setting speed - Adaptive Images now also checks the user agent string. - - If a desktop environment is detected, $mobile_first is automatically - over-ridden to "FALSE". If not Adaptive Images will obey the configured - value. - - This is a safety fallback and requires testing before I revert the - default $mobile_first configured value to TRUE. - -version 1.3.4 (2011/11/10) ------------------------------------------------------------ - - BUG FIXES - * URLs are now allowed to have spaces and other encoded characters in them - * The sharpening function broke on libraries not compiled with the bundled version - of PHP/GD. Adaptive Images now tests the imageconvolution function is available - and gracefully handles cases where it isn't. - - NEW FEATURE - * Instructions to take advantage of high-density displays like Apple's iPhone4 - are now included. Just use the alternative JavaScript snippet. - - NOTES - * Set $mobile_first to default to FALSE. Browsers are inconsistent with their - ability to set cookies before requesting s. For more information visit - http://blog.yoav.ws/2011/09/Preloaders-cookies-and-race-conditions - -version 1.3.3 (2011/10/18) ------------------------------------------------------------ - - BUG FIXES - * Added Gecko to the auto-disabled $mobile_first check: IE and Firefox don't - honour $mobile_first. - - This is because both suffer from a race condition when setting the cookie. - Sometimes it's set before are requested, sometimes not. This could produce - desktop websites with mobile versions on first page load. - - OTHER IMPROVEMENTS - * Changed the HTTP Cache Header from "public" to "private". - - This allows caches that are specific to one user (e.g., browser cache) to store - the image in cache; shared caches (e.g., a proxy server) won't. This should avoid - people behind proxies or other caching mechanisms experiencing wrongly sized images. - -version 1.3.2 (2011/09/06) ------------------------------------------------------------ - Thanks to Oncle Tom - - BUG FIXES - * Internet Explorer was not correctly setting the cookie, and thus breaking badly - * Fixed a possible Cookie Injection, and optimised ai-cookie.php - - NOTES - In testing it seems that Firefox is now behaving properly and setting the cookie - in time. Thus, I've re-instated support for $mobile_first = TRUE on that browser - -version 1.3.1 (2011/09/06) ------------------------------------------------------------ - Thanks to Emilio Bravo - - BUG FIXES - * PNGs now maintain their alpha transparency when scaled down (previously got - black backgrounds where transparency should be) - -version 1.3 (2011/09/04) -------------------------------------------------------------- - Huge thanks to Jordi Boggiano - - NEW FEATURES - * Finalised $mobile_first behaviour and defaulted it to TRUE - BUG FIXES - * Fixed typo which incorrectly set browser cache - OTHER IMPROVEMENTS - * When $mobile_first is FALSE now sends highest configured size instead of original - * Refactored the PHP to be more robust and efficient - * Simplified the JS to a single line and fixed pollution of the global namespace - * Made the .htaccess rule more robust and accurate - - NOTES - Firefox will not honour $mobile_first as set in the CONFIG section. This is - intentional, and required due to a defect in Firefox's behaviour. It does not set - cookies fast enough, and therefor on the first visit to a site would load the - mobile sized image even if JS was enabled. Therefor, AI will not honour the - $mobile_first setting on Firefox based browsers that have JavaScript disabled. - -version 1.3 beta (2011/08/31) --------------------------------------------------------- - - NEW FEATURES - * Added support for Mobile First philosophy (see CONFIG, $mobile_first) - - NOTES - When $mobile_first is set to TRUE it means the mobile sized version of the requested - image will be sent in the event that no cookie is set (likely because JavaScript is - unavailable). If FALSE, the original image is sent. - - There is a known problem with Firefox on a first visit to a site where $mobile_first - is TRUE. It doesn't set the cookie fast enough, so the very first load sends the mobile - size image. All page loads after are fine. Opera, Safari, and Chrome all work OK. - -version 1.2.2 (2011/08/30) ------------------------------------------------------------ - NEW FEATURES - * Unsupported no-javascript solution (see instructions.htm) - -version 1.2.1 (2011/08/26) ------------------------------------------------------------ - NO NEW FEATURES - I have re-branded Responsive-Images to "Adaptive-Images", firstly to help distinguish - this project from the identically named project by Filament Group, and secondly - because it's a more appropriate name. This system actively adapts existing images as - well as "responding" to the visitors viewport to serve an appropriately sized version. - - NOTES - The project is now available on GitHub for those who wish to track it there: - https://github.com/MattWilcox/Adaptive-Images - -version 1.2 (2011/08/21) ------------------------------------------------------------ - Contributions by Fabian Beiner, with thanks :) - NEW FEATURES - * Support for PNG and GIF images - * Added ability to sharpen re-scaled images (see CONFIG, $sharpen) - BUG FIXES - * Better extension detection (.jpeg was failing) - * First-run Firefox bug fixed. The JS must be in-line, in the ! - DETAILS: - Firefox (and potentially others, but not observed anywhere else) was requesting - the first before it loaded the external javascript file, even when in the - . This caused Firefox to load the full-resolution image the very first - time the site was visited. All subsequent page views were fine. - OTHER IMPROVEMENTS - * Cleaned up the .htaccess file and included clear comments on use - * Vastly improved instructions and examples on the downloadable zip - * Since 1.1 fixed issues with browser cache, default cache time now set to 7 days - * Refactored PHP code - -version 1.1 (2011/08/16) ------------------------------------------------------------ - - NEW FEATURES - * Re-engineered the size detection methodology. - - Now detects maximum possible screen size of the device instead of the current - window size. This removes the problem of visitors with small windows caching - small images to the browser, then upon maximising the browser having too small - images for the new screen size. It also simplifies the JS back down to its - original "just dump the size into a cookie" functionality. - - This update removes the following: - - * All JS config options - -version 1.0 (2011/08/09) ------------------------------------------------------------ - - NEW FEATURES - * Headers sent along with the image, for browser side caching (see CONFIG, $browser_cache) - * JavaScript responds to window re-sizes, requests higher res images if required - BUG FIXES - * Fixed the MIME type for JPG's (image/jpeg not image/jpg) - -beta 2 (2011/08/04) ----------------------------------------------------------------- - - NEW FEATURES - * Added the ability to control generated image quality (see CONFIG, $jpg_quality) - * Added configurable resolution breakpoints (see CONFIG, $resolutions) - * Optional Cache checking - defaults to on (see CONFIG, $watch_cache) - BUG FIXES - * The PHP now checks that the GD extension is loaded before proceeding - * Clarified comments further - -beta 1 (2011/08/01) ----------------------------------------------------------------- - - NEW FEATURES - * Initial public release - * Commented the PHP for public consumption - * Added user-configurable cache directory (see CONFIG, $cache_path) - BUG FIXES - * Didn't generate downscaled images due to typo \ No newline at end of file diff --git a/instructions.htm b/instructions.htm deleted file mode 100644 index 8d37d7f..0000000 --- a/instructions.htm +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - -

Adaptive-Images Instructions

-

Basic instructions

-

Copy adaptive-images.php and .htaccess into the root directory of your site. If you already have a htaccess file DO NOT OVERWRITE IT, skip down to the advanced instructions.

-

Copy the following Javascript into the <head> of your site. It MUST go in the head as the first bit of JS, before any other JS. This is because it needs to work as soon as possible, any delay wil have adverse effects.

-
<script>document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/';</script>
-

That's it, you're done. You should proberbly configure some preferences though.

-

NOTE 1: if you would like to take advantage of high-pixel density devices such as the iPhone4 or iPad3 Retina display you can use the following JavaScript instead. - It will send higher-resolution images to such devices - be aware this will mean slower downloads for Retina users, but better images.

-
<script>document.cookie='resolution='+Math.max(screen.width,screen.height)+("devicePixelRatio" in window ? ","+devicePixelRatio : ",1")+'; path=/';</script>
-

NOTE 2: you do not need the ai-cookie.php file unless you are using the alternate method of detecting the users screen size. So delete it if you like, no one likes mess.

-

NOTE 3: If you are extra paranoid about security you can have the ai-cache directory sit outside of your web-root so it's not publicly accessible. Just set the paths properly in the .htaccess file and the .php file.

- -

You already have a .htaccess file

-

I strongly advise you to duplicate that file so you can revert to it if things go pear-shaped.

-

Open your existing .htaccess file and edit the contents. You'll need to look and see if there is a section that begins with the following:

-

<IfModule mod_rewrite.c>

-

If there is, then you need to add the following lines into that block:

- -
# Adaptive-Images -----------------------------------------------------------------------------------
-
-# Add any directories you wish to omit from the Adaptive-Images process on a new line, as follows:
-# RewriteCond %{REQUEST_URI} !some-directory
-# RewriteCond %{REQUEST_URI} !another-directory
-
-RewriteCond %{REQUEST_URI} !assets
-
-# Send any GIF, JPG, or PNG request that IS NOT stored inside one of the above directories
-# to adaptive-images.php so we can select appropriately sized versions
-RewriteRule \.(?:jpe?g|gif|png)$ adaptive-images.php
-
-# END Adaptive-Images -------------------------------------------------------------------------------
- -

If you don't have a code block then simply copy and paste the following into your file instead:

- -
<IfModule mod_rewrite.c>
-  Options +FollowSymlinks
-  RewriteEngine On
-
-  # Adaptive-Images -----------------------------------------------------------------------------------
-
-  # Add any directories you wish to omit from the Adaptive-Images process on a new line, as follows:
-  # RewriteCond %{REQUEST_URI} !some-directory
-  # RewriteCond %{REQUEST_URI} !another-directory
-
-  RewriteCond %{REQUEST_URI} !assets
-
-  # Send any GIF, JPG, or PNG request that IS NOT stored inside one of the above directories
-  # to adaptive-images.php so we can select appropriately sized versions
-  RewriteRule \.(?:jpe?g|gif|png)$ adaptive-images.php
-
-  # END Adaptive-Images -------------------------------------------------------------------------------
-</IfModule>
- -

Additional settings and configuration

-

.htaccess

-

Instructions are in the file as comments (any line that starts with a # is a comment, and doesn't actually do anything)

-

Follow the instructions inside that code to specify any directories you don't want to use Adaptive-Images on.

- -

PHP

-

You can now open the php file and have a play with the settings that are in the CONFIG area. By default it looks like this:

- -
/* CONFIG ----------------------------------------------------------------------------------------------------------- */
-
-$resolutions   = array(1382, 992, 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   = 80; // 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?
-$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)
-
-/* END CONFIG ----------------------------------------------------------------------------------------------------------
------------------------- Don't edit anything after this line unless you know what you're doing -------------------------
---------------------------------------------------------------------------------------------------------------------- */
-

$resolutions are the screen widths we'll work with. In the default it will store a re-sized image for large screens, normal screens, tablets, phones, and tiny phones.

-

In general, if you're using a responsive design in CSS, these breakpoints will be exactly the same as the ones you use in your media queries.

-

$cache_path If you don't like the cached images being written to that folder, you can put it somewhere else. Just put the path to the folder here and make sure you create it on the server if for some reason that couldn't be done autmoatically by adaptive-images.php.

-

$sharpen Will perform a subtle sharpening on the rescaled images. Usually this is fine, but you may want to turn it off if your server is very very busy.

-

$watch_cache If your server gets very busy it may help performance to turn this to FALSE. It will mean however that you will have to manually clear out the cache directory if you change a resource file

- -

Alternate method for those who can't rely on JavaScript

- -

One of the weaknesses of the Adaptive Images process is its reliance on JavaScript to detect the visitors screen size, and set a cookie with that screen size inside it. The following is a solution for people who need the system to work without the use of JavaScript, but it does have a major caveat which is why this is not the default method, and why it is "unsupported" (I'm not going to troubleshoot problems you have with this method).

- -

The alternative method

-

Do not use the JavaScript as explained above, but instead, ABOVE your normal CSS, add the following into the head:

-
<style>
- @media only screen and (max-device-width: 479px) {
-   html { background-image:url(ai-cookie.php?maxwidth=479); } }
- @media only screen and (min-device-width: 480px) and (max-device-width: 767px) {
-   html { background-image:url(ai-cookie.php?maxwidth=767); } }
- @media only screen and (min-device-width: 768px) and (max-device-width: 991px) {
-   html { background-image:url(ai-cookie.php?maxwidth=991); } }
- @media only screen and (min-device-width: 992px) and (max-device-width: 1381px) {
-   html { background-image:url(ai-cookie.php?maxwidth=1381); } }
- @media only screen and (min-device-width: 1382px) {
-   html { background-image:url(ai-cookie.php?maxwidth=unknown); } }
-</style>
-

If you use this method you will need to ensure the widths here match those in your adaptive-images.php file, you will also need to have the ai-cookie.php file in the root of your website (no one else needs this file).

- -

The caveat

-

Using this method instead of the JS method makes it likely that on the very first visit to your site, the images sent to the visitor will be the original full-scale versions. However, ALL subsequent pages on your site will work properly. What that means is that, really, this solution is only viable if you've got $mobile_first set to FALSE. Otherwise, the majority of people who visit your site will experience images too small for their computer on the very first visit.

-

The reason is to do with how browsers load web pages. The first thing a browser does is load the HTML, in the order it's written - so for a normal AI install it loads the HTML and see's the embeded JavaScript and immediately executes that JavaScript - which writes the cookie. It then carries on loading the rest of the page in the order it finds it. Long story short - it means that when it finds an image tag and asks the server for it, it already has a cookie stored.

-

That's not likely to be the case if you use the CSS method. Because the CSS method relies on an external file - it has to ask the server for the "background-image", which is really just a bit of PHP to set a cookie. The problem is that when a browser loads external files like that, it doesn't stop loading the HTML, it carries on doing that at the same time as waiting for the external file. Which means that it can get to an image tag before the server has finished loading that PHP file. This is only an issue on the very first page load, and AI has smart fallbacks to deal with a no-cookie situation.

- -

Troubleshooting

-

Most of the time people report problems it is due to one of two things:

-

If images vanish, there is something wrong with your .htaccess configuration. This happens mostly on WordPress sites - it's because the server, and wordpress, have specific requirements that are different from most servers. You'll have to play about in the .htaccess file and read up on how to use ModRewrite.

-

If you're seeing error images (big black ones) That's AI working, so your .htaccess is fine. Read the messages on the image. Most of the time you'll only see this problem because your server requires less strict permissions to write to the disc. Try setting the ai-cache directory to 775, and if all else fails use 777 - but be aware this is not very secure if you're on a shared server, and you ought to instead contact your administrator to get the server set up properly.

- - \ No newline at end of file diff --git a/instructions_de.htm b/instructions_de.htm deleted file mode 100644 index e216fd1..0000000 --- a/instructions_de.htm +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - - -

Adaptive-Images Installationsanweisungen

-

Basis Anweisungen

-

Kopieren Sie adaptive-images.php und .htaccess - in das Hauptverzeichniss ihres Internetauftritts. - Wenn Sie bereits eine htaccess Datei haben BITTE NICHT ÜBERSCHREIBEN, lesen sie die dafür vorgesehenen Instruktionen.

-

Erstellen Sie ein Verzeichniss mit dem Namen ai-cache im Hauptverzeichniss - mit Schreibberechtigung (CHMOD 777).

-

Kopieren Sie folgendes Javascript in den <head> Bereich ihrer Seiten. - Das Script MUSS sich im head Bereich befinden damit es ausgeführt wird bevor - die gesamte Seite geladen ist und die ersten Bilder vom Server ausgeliefert werden.

-
<script>document.cookie='resolution='+Math.max(screen.width,
-screen.height)+'; path=/';</script>
-

Das wars. Sie sind fertig

-

ANMERKUNG: Die ai-cookie.php Datei wird normalerweise nicht - benötigt. Nur beim Einsatz der Alternativen Methode - zum Feststellen der Displaygrösse wird sie benötigt ansonsten kann sie gelöscht werden.

- -

Sie haben bereits eine .htaccess Datei

-

Sichern Sie bitte diese Datei bevor Sie Änderungen daran vornehmen.

-

Öffnen Sie bitte ihre bestehende .htaccess Datei und editieren Sie den Inhalt. - Suchen Sie nach einem Abschnitt suchen der so beginnt:

-

<IfModule mod_rewrite.c>

-

Sollten Sie ihn gefunden haben kopieren Sie folgenden Code in den Bereich:

- -
# Adaptive-Images -----------------------------------------------------------------------------------
-
-# Add any directories you wish to omit from the Adaptive-Images process on a new 
-line, as follows:
-# RewriteCond %{REQUEST_URI} !some-directory
-# RewriteCond %{REQUEST_URI} !another-directory
-
-RewriteCond %{REQUEST_URI} !assets
-
-# Send any GIF, JPG, or PNG request that IS NOT stored inside one of the above 
-directories
-# to adaptive-images.php so we can select appropriately sized versions
-RewriteRule \.(?:jpe?g|gif|png)$ adaptive-images.php
-
-# END Adaptive-Images -------------------------------------------------------------------------------
- -

Gibt es keinen solchen Abschnitt in ihrer Datei kopieren Sie stattdesen folgenden Code in die Datei:

- -
<IfModule mod_rewrite.c>
-  Options +FollowSymlinks
-  RewriteEngine On
-
-  # Adaptive-Images -----------------------------------------------------------------------------------
-
-  # Add any directories you wish to omit from the Adaptive-Images process on a 
-  new line, as follows:
-  # RewriteCond %{REQUEST_URI} !some-directory
-  # RewriteCond %{REQUEST_URI} !another-directory
-
-  RewriteCond %{REQUEST_URI} !assets
-
-  # Send any GIF, JPG, or PNG request that IS NOT stored inside one of the above 
-  directories
-  # to adaptive-images.php so we can select appropriately sized versions
-  RewriteRule \.(?:jpe?g|gif|png)$ adaptive-images.php
-
-  # END Adaptive-Images -------------------------------------------------------------------------------
-</IfModule>
- -

Weitere Einstellungen

-

.htaccess

-

Anweisungen sind in der Datei als Kommentare enthalten (alle Zeilen die - mit # beginnen sind Kommentare und werden nicht ausgeführt)

-

Folgen Sie den Anweisungen im Code um Verzeichnisse die nicht mit - Adaptive-Images benutzt werden sollen einzutragen.

- -

PHP

-

Sie können die PHP-Datei öffnen und die Einstellungen im CONFIG Bereich ändern. - Die Standardwerte sehen so aus:

- -
/* CONFIG ----------------------------------------------------------------------------------------------------------- */
-
-$resolutions   = array(1382,992,768,480,320); // Die Auflösungsschritte für die Bilder erzeugt werden (Bildschirmbreite in Pixel)
-$cache_path    = "ai-cache"; // Wo die verkleinerten Bilder gespeichert werden.  Der Ordner muss beschreibbar sein.
-$jpg_quality   = 80; // Die Qualität der erzeugten JPGs 0 bis 100
-$sharpen       = TRUE; // Verkleinerte Bilder verlieren an Schärfe, bei TRUE werden die Bilder geschärft 
-$watch_cache   = TRUE; // stellt sicher das neu hochgeladene Bilder neu verkleinert werden
-$browser_cache = 60*60*24*7; // Die Zeit in Sekunden für den BROWSER cache (Standard 7 Tage)
-$mobile_first  = TRUE; // Ist kein Cookie vorhanden wird zuerst die mobile Version gesendet (wenn FALSE, wird das grösste Bild gesendet)
-
-/* END CONFIG ----------------------------------------------------------------------------------------------------------
------------------------- Verändern Sie nichts nach dieser Zeile wenn Sie nicht wissen was Sie tun -------------------------
---------------------------------------------------------------------------------------------------------------------- */
-

$resolutions sind die Bildschirmauflösungen mit denen gearbeitet wird. - Als Standard werden verkleinerte Bilder für grosse Bildschirme, normale Bildschirme, - Tablets, Smartphones, und Handys gespeichert.

-

Im allgemeinen, wenn Sie die CSS Methode nutzen, werden diese Auflösungen - dieselben wie in den 'media queries' sein.

-

$cache_path Der Pfad in den die Bilder zwischengespeichert werden. - Er kann beliebig geändert werden. Der Pfad wird hier eingetragen und es muss - sichergestellt sein das er auf dem Server existiert.

-

$sharpen Die bilder werden nach dem Verkleinern geschärft. - Normal funktioniert das gut sollte ihr Server sehr sehr ausgelastet sein kann es hier abgeschaltet werdn. .

-

$watch_cache Bei Performanceproblemen ihres Servers kann diese Option abgeschaltet werden. - Sollten Sie allerdings ihre Quell-Bilder ersetzen müssen Sie den Cache Ordner manuell leeren.

-

$mobile_first Wenn TRUE und kein cookie ist gesetzt, sendet Adaptive - Images Bilder in der 'mobilen' Auflösung. Wenn FALSE gesetzt ist werden die am - höchten aufgelössten Bilder gesendet.

- -

Alternative Methode ohne JavaScript

- -

Eine Schwäche von Adaptive Images ist das JavaScript zum Erkennen der -Bildschirmgrösse des Besuchers benötigt wird. -Im folgenden wird eine Methode ohne Javascript gezeigt. -Diese Methode funktioniert unter Vorbehalt wird allerdings vom Autor nicht empfohlen und nicht unterstützt. -

- -

Die alternative Methode

-

Benötigt kein JavaScript stattdessen aber, muss ÜBER ihrem normalen -CSS, folgende Zeilen eingefügt werden:

-
<style>
- @media only screen and (max-device-width: 479px) {
-   html { background-image:url(ai-cookie.php?maxwidth=479); } }
- @media only screen and (min-device-width: 480px) and (max-device-width: 767px) {
-   html { background-image:url(ai-cookie.php?maxwidth=767); } }
- @media only screen and (min-device-width: 768px) and (max-device-width: 991px) {
-   html { background-image:url(ai-cookie.php?maxwidth=991); } }
- @media only screen and (min-device-width: 992px) and (max-device-width: 1381px) {
-   html { background-image:url(ai-cookie.php?maxwidth=1381); } }
- @media only screen and (min-device-width: 1382px) {
-   html { background-image:url(ai-cookie.php?maxwidth=unknown); } }
-</style>
-

Wenn Sie diese Mehode verwenden müssen Sie sicherstellen das die verwendeten -Bildschirmauflösungen dennen in Ihrer adaptive-images.php Datei entsprechen, -Sie benötigen zudem die ai-cookie.php Datei im Hauptverzeichniss ihres Internetauftritts. -(ansonsten wird diese Datei nicht benötigt).

- -

Der Vorbehalt

-

Benutzen Sie diese Methode anstatt JS ist es möglich das besucher bei ihrem -ersten Besuch ihrer Seiten, die original hoch aufgelössten Bilder gesendet bekommen. -ALLE Seiten ihres Auftritts werden wie vorgesehen funktionieren. -Das bedeutet allerdings das Sie die Option $mobile_first auf FALSE setzen müssen. -Ansonsten werden die meisten ihrer Besucher feststellen das die angezeigten Bilder, - bei ihrem ersten Besuch zu klein dargestellt werden. -Otherwise, the majority of people who -

-

Der Grund dafür ist die Reihenfolge wie Browser Internetseiten verarbeiten. -Als erstes wird das HTML geladen, und in der Reihenfolge wie es geschrieben wurde abgearbeitet. -Das eingebettete JavaScript wird sofort ausgeführt und erzeugt das Cookie. -Danach werden Bilder in der Reihenfolge ihres Auftrettens geladen. das heisst -werden die ersten Bilder vom Server angefordert ist das Cookie mit der Bildschirmgrösse -bereits geschrieben.

-

Das ist bei der CSS Methode nicht unbedingt der Fall. Die CSS -Methode setzt eine externe Datei voraus - sie fordert vom Server -"background-image" an, welche von der PHP Datei nur benötigt wird um das Cookie zu setzen. -Das Problem ist das der Browser beim laden der externen Datein nicht anhält, -er arbeitet weiter während er auf die externe datei wartet. Das bedeutet das -schon Bilddateien angefordert werden können bevor die PHP Datei abgearbeitet wurde -und somit noch kein Cookie gesetzt wurde. Das wiederum heisst, daß wenn $mobile_first TRUE ist -die für mobile Geräte verkleinerten Bilder gesendet werden. Aber nur wenn die -allererste Seite geladen wird.

- - \ No newline at end of file diff --git a/readme.textile b/readme.textile index 14fb18e..b3a6678 100644 --- a/readme.textile +++ b/readme.textile @@ -1,21 +1,95 @@ -h1. Adaptive Images +h1. JavaScript Snippet for Detecting Screen Width (über-extended) -Is a solution to automatically create, cache, and deliver device-appropriate versions of your website's content images. It does not require you to change your mark-up. It is intended for use with "Responsive Designs":http://www.abookapart.com/products/responsive-web-design and to be combined with "Fluid Image":http://unstoppablerobotninja.com/entry/fluid-images/ techniques. +**Meant to be used with Adaptive Images and its forks, but can of course be altered to meet other needs as well.** -h2. Benefits +Since I "found out":http://www.quirksmode.org/mobile/tableViewport.html that the use of screen.width doesn’t always leave you with reliable results in conjunction with devicepixelratio, I looked for another solution to do it. And here is how. -* Ensures you and your visitors are not wasting bandwidth delivering images at a higher resolution than the vistor needs. -* Will work on your existing site, as it requires no changes to your mark-up. -* Is device agnostic (it works by detecting the size of the visitors screen) -* Is CMS agnostic (it manages its own image re-sizing, and will work on any CMS or even on flat HTML pages) -* Is entirely automatic. Once added to your site, you need do no further work. -* Highly configurable -** Set the resolutions you want to become adaptive (usually the same as the ones in your CSS @media queries) -** Choose where you want the cached files to be stored -** Configure directories to ignore (protect certain directories so AI is not applied to images within them) +**If you like serving for high-ppi ("retina") devices right: this is for you!** -Find out more, and view examples at "http://adaptive-images.com":http://adaptive-images.com -h2. Legal +h2. The Problem -Adaptive Images by Matt Wilcox is licensed under a "Creative Commons Attribution 3.0 Unported License":http://creativecommons.org/licenses/by/3.0/ \ No newline at end of file +When using AI, we rely on **screen.width** and **devicepixelratio** to detect the resolution (screen width and pixel ratio) to save it in the cookie. If we use the “long” version of the JS line to detect if a high-ppi (“retina”) device is present, we afterwards multiply the found screen width with the pixel ratio – doubling the image size to be served. This will work fine in browsers which actually return “wrong” values for screen.width: they report the theoretical screen resolution = CSS pixels = device independent pixels = dips. So what we’re basically doing is: relying on “bad behavior”; relying on a buggy and wrong implementation. + +Why? Because "according to quirksmode":http://www.quirksmode.org/mobile/tableViewport.html, screen.width is actually meant to return the **real physical size** of the screen – _not the dips!_ + +So: if you “accidentially” serve to a browser that does it _right_, you end up doubling the already doubled screen size – ergo image size. +And if you’re like me, taking into account even device pixel ratios >2 (possible with "the fork I’m using":https://github.com/Darkwing371/Adaptive-Images-Uber-Extended), it could happen that you serve a 5760px image to a screen that has only 640px of theoretical width (worst case). + + +h2. The Reality Check + +So is this a real world problem? Decide for yourself. + +"Quirksmode":http://www.quirksmode.org/mobile/tableViewport.html reports, that on new Android phones, Blackberries, newer Nokias and on mobile Firefoxes, the screen size which screen.width would report, is based on the actual device pixels. Thus being right, it would actually cause us problems. + +So with ppks compatiblity table in mind, I went downtown to do a real life countercheck. Here are my findings: + + + + + + + + + + + + + + + + + + + + + + + +
**Results of two approaches of screen width detection**
Devicescreen.widthmediaMatch
iPad1024,21024,2
iPhone 4480,2480,2
iPhone 5568,2568,2
MacBook Pro 13"1280,21280,2
MackBook Pro 15"1440,11440,1
MackBook Air 11"*1366,1**1368,1*
MacBook Air 13"1440,11440,1
Sony Xperia (Chrome)*1794,3**600,3*
HTC One (Chrome)*1920,3**640,3*
HTC One X (Chrome)1280,21280,2
Samsung Galaxa S III1280,21280,2
Samsung Galaxy Note II1280,21280,2
Samsung Galaxy Tab 21280,11280,1
Huawei Ascend800,1.5800,1.5
Nokia Lumia800,1800,1
+ +We see it’s true: even in this quick test there are some cases **right now**, where we would actually be in trouble, when we’d try to care for high-ppi devices in the “old-fashioned way”. I’d say that on about 80% of the actual devices out there, there will be no big problems. But this might change with new devices and new browsers on new devices – and since we care for achieving excellence in being future friendly, let’s make it a 100% of compatiblity today. ;) + + + +h2. The Solution + +I once came across "this thread on stackoverflow":http://stackoverflow.com/questions/6850164/get-the-device-width-in-javascript and became aware of the possibility using media queries via **matchMedia** in JS. I used this principle to detect the devices screen size in a small for-loop using the media queries. (Have a look at the code for details; it’s heavily commented.) + +h4. Why should this be favored? + +*Because it _uses_ CSS-pixels by design, because of the media queries – so it does of course return our desired dips.* + +* If media queries themselfes aren’t implemented (or buggy) in a browser/device, our responsive site is in trouble anyway. +* And it can mean, that the device is _so_ old, that there is no way having a high-ppi display present. +* Or maybe it means, that there is IE < 9 running. (See first point.) + +So let’s just count on having media queries available. I dare to raise the assumption, that media queries’ max-device-width is "completly implemented":http://www.browsersupport.net/CSS/%40media_%28max-device-width%29 in every browser on a new high-ppi device out there – and will be implemented "in future browsers":http://caniuse.com/#feat=matchmedia on new devices. + +I’d say, that sounds pretty reliable. + +And in case something should fail, we have our original one-liner to fall back to and simply abstain from serving high-ppi images. So nothing to lose here actually, **it’s progressive enhancement.** + +Remember: +If this whole JavaScript thing should fail _at all_, we’ll always have a fallback in php to serve at least some appropriate image sizes. + + +h2. Dude, this is huge – compared to the original one-liner! + +I know. This script seems totally overkill at first glance, when you got used to Matts original one line of code (that’s why my work is going by the name of **“über-extended”**). And well, I could have had this written in one line too (a long line), but I decided to comment all of my work – to make it easier to read, for understanding what and why it does things, and for others to maybe even add further improvements. + +At first I was concerned about speed of execution too, but I tested it on several occasions: it did no harm and worked reliable. A browser that would set our cookie “too late” for whatever reason, doesn’t set it too late because of JS execution time. There are other things to be held responsible for, when something like this happens. JavaScript is actually executed quicker than I thought, even on small and old mobile devices. + +Nonetheless try putting the snippet on topmost location of your sites head! (And I’m pretty sure you know how to "minify":http://www.minifyjavascript.com/ it, if you want that.) + + + +h2. So what’s the bottom line a.k.a. tl;dr? + +* Don’t let our nice Adaptive Images solution rely on wrong and buggy browser implementations any more. +* Be more future friendly, especially to devices that will actually do things _right_. +* Have a more reliable and robust foundation for the math. +* Peace of mind while always having the “oldschool version” as a fallback built-in. + +**Use the new JS snippet now!** … and have a gaze at the code! :)