Skip to content

Commit

Permalink
Smarter handling of Retina type displays
Browse files Browse the repository at this point in the history
Previous AI behaviour meant that supporting Retina required adding very
high values in the $resolutions array. This is sub-optimal:

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 this case could be far too large for most
people.

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.

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.
  • Loading branch information
MattWilcox committed Apr 14, 2012
1 parent 2daeb09 commit a6f8124
Showing 1 changed file with 36 additions and 10 deletions.
46 changes: 36 additions & 10 deletions adaptive-images.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/* PROJECT INFO --------------------------------------------------------------------------------------------------------
Version: 1.4.1
Version: 1.5
Changelog: http://adaptive-images.com/changelog.txt
Homepage: http://adaptive-images.com
Expand Down Expand Up @@ -241,20 +241,46 @@ function generateImage($source_file, $cache_file, $resolution) {

/* Check to see if a valid cookie exists */
if (isset($_COOKIE['resolution'])) {
if (is_numeric($_COOKIE['resolution'])) {
$client_width = (int) $_COOKIE["resolution"]; // store the cookie value in a variable
$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", "", time() -1); // 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)
$pixel_density = $cookie_data[1]; // the device's pixel density factor (physical pixels per CSS pixel)
$total_width = $client_width;

/* the client width in the cookie is valid, now fit that number into the correct resolution break point */
rsort($resolutions); // make sure the supplied break-points are in reverse size order
$resolution = $resolutions[0]; // by default it's the largest supported break-point
$resolution = $resolutions[0]; // by default use the largest supported break-point

foreach ($resolutions as $break_point) { // filter down
if ($client_width <= $break_point) {
$resolution = $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

// if that total width is bigger than the largest resolution, define a new one, which will be a
// multiple of one of the defined resolutions.
if($total_width < $resolutions[0]){
$resolution = $total_width;
}
// otherwise fit the 'high dpi' width into the existing breakpoints if they're big enough already
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;
}
}
}
} else {
setcookie("resolution", "", time() -1); // delete the mangled cookie
}
}

Expand Down

0 comments on commit a6f8124

Please sign in to comment.