21

I found many questions about Retina Display, but none of the answers were on the server side.

I would like to deliver a different image according to the screen, ex (in PHP):

if( $is_retina)
    $thumbnail = get_image( $item_photo, 'thumbnail_retina' ) ;
else
    $thumbnail = get_image( $item_photo, 'thumbnail' ) ;

Can you see a way of dealing with this?

I can only imagine a test in JavaScript, setting a Cookie. However this requires an initial exchange to set it. Anyone have a better solution?

Cookie setting code:

(function(){
  if( document.cookie.indexOf('device_pixel_ratio') == -1
      && 'devicePixelRatio' in window
      && window.devicePixelRatio == 2 ){

    document.cookie = 'device_pixel_ratio=' + window.devicePixelRatio + ';';
    window.location.reload();
  }
})();
rogerdpack
  • 62,887
  • 36
  • 269
  • 388
chriscatfr
  • 2,592
  • 3
  • 24
  • 32

3 Answers3

20

Alright since it seems there's no better way for the moment, here is my solution combining JS, PHP and Cookies.

I hope there will be better answers in the future

<?php
    if( isset($_COOKIE["device_pixel_ratio"]) ){
        $is_retina = ( $_COOKIE["device_pixel_ratio"] >= 2 );

        if( $is_retina)
            $thumbnail = get_image( $item_photo, 'thumbnail_retina' ) ;
        else
            $thumbnail = get_image( $item_photo, 'thumbnail' ) ;

    }else{
?>
<script language="javascript">
(function(){
  if( document.cookie.indexOf('device_pixel_ratio') == -1
      && 'devicePixelRatio' in window
      && window.devicePixelRatio == 2 ){

    var date = new Date();
    date.setTime( date.getTime() + 3600000 );

    document.cookie = 'device_pixel_ratio=' + window.devicePixelRatio + ';' +  ' expires=' + date.toUTCString() +'; path=/';
    //if cookies are not blocked, reload the page
    if(document.cookie.indexOf('device_pixel_ratio') != -1) {
        window.location.reload();
    }
  }
})();
</script>
<?php } ?>

in function.php :

add_action( 'init', 'CJG_retina' );

function CJG_retina(){

    global $is_retina;  
    $is_retina = isset( $_COOKIE["device_pixel_ratio"] ) AND $_COOKIE["device_pixel_ratio"] >= 2;
}

Then after I can use the following GLOBAL:

global $is_retina; or $GLOBALS['is_retina'];

chriscatfr
  • 2,592
  • 3
  • 24
  • 32
10

As you do not specify for what exact use-case you are needing this and i do not really see a use-case for the server knowing what resolution the client wants it's images in (in my opinion the client should decide) here is my suggestion:

Use something like Retina.js or use the srcset attribute <img src="low-res.jpg" srcset="medium-res.jpg 1.5x, high-res.jpg 2x">

This way you could also leverage browser caching of the images. which you can't do if you have one url for two different image sizes. Even if its an automatically created/updated image caching works using last-modified or etag headers.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
smurfy
  • 616
  • 5
  • 8
  • Any preference between retina.js and srcset here? – rogerdpack May 06 '17 at 20:37
  • 2
    in 2013 srcset was expected or very new. You couldn't use it even on the new Retina computers. Now in 2017 it is a better choice. – chriscatfr May 07 '17 at 16:42
  • 1
    I prefer srcset, because it works without javascript. Also you can control which img tag you want to be available with a retina image and which image is not available. But if you provide a retina image for all images and want full compatibility a javascript solution like retina.js would serve you better. – smurfy May 07 '17 at 19:26
  • See also https://stackoverflow.com/q/19689715/32453 for other ways to use either javascript or CSS (client-side stuff) similarly, just as a note to followers. – rogerdpack May 23 '17 at 20:09
  • [More info about srcset here](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images), including examples. – Mentalist Dec 05 '18 at 07:04
1

I'm not sure exactly how, but the pure PHP way of figuring this out would be using get_browser which returns the browser version and SOME capabilities. This may be able to tell you some information that MAY lead to whether its running on a retina.

http://php.net/manual/en/function.get-browser.php

Additionally, you can look at $_SERVER['HTTP_USER_AGENT'] which will tell you the things about the device. then you need a list of Devices that have retinas and do a comparison to get the answer.

Doing your retina detection in the JS is probably much easier and foolproof.

Francis Yaconiello
  • 10,829
  • 2
  • 35
  • 54