Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

added @2x retina-image support #95

Open
wants to merge 2 commits into from

2 participants

@michelkaeser

This pull-request will enable support for serving @2x retina image support. It checks (if on retina device) if a @2x version exists - and serves it.

@michelkaeser michelkaeser commented on the diff
adaptive-images.php
@@ -29,8 +29,9 @@
$requested_file = basename($requested_uri);
$source_file = $document_root.$requested_uri;
$resolution = FALSE;
+$retina = FALSE;

I thought I need this variable at the beginning, but it doesn't seem to be the case anymore. However, I thought it may be smart to keep it as it allows to check for retina inside the generateImage method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@cferdinandi

Isn't this included in the $pixel_density check that AI already does?

@michelkaeser

@cferdinandi it used $pixel_density for size calculation - so if you have retina files only this isn't a problem. I like to have non-retina (default) and retina files however - so AI needs to know about them.

@cferdinandi

Sorry, I'm not understanding. So you already have two optimized file sizes made that you want AI to choose from before doing it's optimization?

@michelkaeser

Correctly. I'm not even sure anymore if this makes sense with AI, but I've seen it like this:

  • non-retina img (2000x2000)
  • retina img (4000x4000)

Now a smartphone with 960 screen requests the image. Since AI already checks it's pixel density this will either be serves as 960xX or 1920xX (with DPI 2).

However, this won't really be sharp, as with DPI 2 (so the 1920xX img) it would actually need to be 3840px to be fully sharp -> therefor we need to serve the retina one and set calculated pixel size to *2.

Of course this is somehow agains the idea of AI to serve size optimized images, but we still save a few KBs and serve real retina images, providing full sharpness.

I might be totally wrong about the mechanism how AI RELLY works, but that's what I've understand...and therefor needed this "tweak".

Edit: well, the pull-rqst is missing multiplying dimension*2...the core...

@cferdinandi

Ah gotcha!

So I made a few mods to AI to work around this situation myself:

  1. I use percentage-based grids, so I created a variable for the content container width as a percentage (ex. $wrap_width = 0.88 and multiply that by the screen size to get the actual width I need for the image. This value replaces the current $total_width variable. The screen could be 1,000 pixels across, but if the image container is only 400px, that's how big my image needs to be.

  2. If the $pixel_density does not equal 1, it continues to do it's normal thing, but it's getting a size requirement based on the actual. So using the above example, a 400px container on a 2x screen updates the $total_width requirement to 800px.

  3. AI does it's thing and creates an image to fit that size.

On my site itself, I serve retina density images as the default and let AI downscale them as needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 3, 2013
  1. @michelkaeser
Commits on Jan 6, 2013
  1. @michelkaeser
This page is out of date. Refresh to see the latest.
Showing with 18 additions and 5 deletions.
  1. +18 −5 adaptive-images.php
View
23 adaptive-images.php
@@ -18,6 +18,7 @@
$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)
+$retina_suffix = "@2x"; // string to append to high-resolution images (e.g. image.png -> image@2x.png)
/* END CONFIG ----------------------------------------------------------------------------------------------------------
------------------------ Don't edit anything after this line unless you know what you're doing -------------------------
@@ -29,8 +30,9 @@
$requested_file = basename($requested_uri);
$source_file = $document_root.$requested_uri;
$resolution = FALSE;
+$retina = FALSE;

I thought I need this variable at the beginning, but it doesn't seem to be the case anymore. However, I thought it may be smart to keep it as it allows to check for retina inside the generateImage method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
-/* Mobile detection
+/* Mobile detection
NOTE: only used in the event a cookie isn't available. */
function is_mobile() {
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
@@ -130,7 +132,7 @@ function refreshCache($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) {
+function generateImage($source_file, $cache_file, $resolution, $retina) {
global $sharpen, $jpg_quality;
$extension = strtolower(pathinfo($source_file, PATHINFO_EXTENSION));
@@ -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);
@@ -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)) {
@@ -264,6 +266,17 @@ function generateImage($source_file, $cache_file, $resolution) {
if($pixel_density != 1) {
$total_width = $client_width * $pixel_density; // required physical pixel width of the image
+ // @2x retina-image replacement
+ $extension = strtolower(pathinfo($source_file, PATHINFO_EXTENSION));
+ $retina_file = str_replace(".$extension", "$retina_suffix.$extension", $source_file);
+
+ // check if the file exists at all
+ if (file_exists($retina_file)) {
+ $requested_uri = str_replace(".$extension", "$retina_suffix.$extension", $requested_uri);
+ $source_file = $retina_file;
+ $retina = TRUE;
+ }
+
// 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
@@ -318,5 +331,5 @@ function generateImage($source_file, $cache_file, $resolution) {
}
/* It exists as a source file, and it doesn't exist cached - lets make one: */
-$file = generateImage($source_file, $cache_file, $resolution);
+$file = generateImage($source_file, $cache_file, $resolution, $retina);
sendImage($file, $browser_cache);
Something went wrong with that request. Please try again.