detect retina (HD) display on the server side

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();
  }
})();

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

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'];

Solution 2

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.

Solution 3

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.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply