Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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();
  }
})();
like image 203
chriscatfr Avatar asked Mar 05 '13 21:03

chriscatfr


3 Answers

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

like image 94
chriscatfr Avatar answered Nov 11 '22 02:11

chriscatfr


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.

like image 33
smurfy Avatar answered Nov 11 '22 04:11

smurfy


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.

like image 1
Francis Yaconiello Avatar answered Nov 11 '22 04:11

Francis Yaconiello