0

I have a view showing several nodes that have photos stored in an image field. It works great, but doesn't look so sharp on HiDPI displays (or when the page is zoomed-in on a traditional display) because the image file that views produces is exactly the size used in HTML. Views is giving me something like this:

<img src="my-image-300x200.jpg" width="300" height="200">

But I think what I'd like views to do is produce something like:

<img src="my-image-600x400.jpg" width="300" height="200">

This way I'm loading images bigger than necessary (downside = slower page load), but it would seem worth it to me because I could get the images to look nice and crisp when the client has a device pixel ratio > 1.

My images in these nodes are not always the same aspect ratio.

Any thoughts on how to get views to produce the image and markup above, or perhaps how to approach this problem a different way?

3
  • I think a more common solution would be to output the larger image through views, and use CSS to dumbnail the images down. Unless there's a pre-built module that does just this (could always happen) that will be less work
    – Clive
    Oct 9, 2014 at 17:25
  • @Clive that's a good idea. But how would I do that if my CSS is not aware of the exact dimensions of each image? For example, my view is scaling images to be within 300x300. Some images might be 300x200. Others might be 100x300.
    – Sean
    Oct 9, 2014 at 17:30
  • Usually (not always, sometimes it doesn't fit the scenario) you would pick one dimension to scale by, and set the other to auto. So img { max-width: 300px; height: auto; } or img { max-height: 200px; width: auto; }. Kinda depends on the effect you're going for
    – Clive
    Oct 9, 2014 at 17:40

2 Answers 2

2

srcset has (or will have) decent support in browsers. What I do, is make _2x image styles for everything, and then do a custom theme_image_style():

/**
 * Implements theme_image_style().
 */
function MYTHEME_image_style($variables) {
  // Determine the dimensions of the styled image.
  $dimensions = array(
    'width' => $variables['width'],
    'height' => $variables['height'],
  );

  image_style_transform_dimensions($variables['style_name'], $dimensions);

  $variables['width'] = $dimensions['width'];
  $variables['height'] = $dimensions['height'];

  // Determine the URL for the styled image.
  $path = $variables['path'];

  $variables['path'] = image_style_url($variables['style_name'], $path);

  // See if we have alternates for the srcset
  $image_styles = &drupal_static(__FUNCTION__);
  if (empty($image_styles)) {
    $image_styles = array_keys(image_styles());
  }

  $variables['srcset'] = array('1x' => $variables['path']);

  if (in_array($variables['style_name'] . '_2x', $image_styles)) {
    $variables['srcset']['2x'] = image_style_url($variables['style_name'] . '_2x', $path);
  }

  return theme('image', $variables);
}

and then

/**
 * Implements theme_image().
 */
function MYTHEME_image($variables) {
  $attributes = $variables['attributes'];
  $attributes['src'] = file_create_url($variables['path']);

  // Add in normal attributes.
  foreach (array('alt', 'title', 'width', 'height') as $key) {
    if (isset($variables[$key])) {
      $attributes[$key] = $variables[$key];
    }
  }

  // Add in our srcset if we have two or more.
  if (count($variables['srcset']) >= 2) {
    $srcset = array();

    foreach ($variables['srcset'] as $size => $path) {
      $srcset[] = file_create_url($path) . ' ' . $size;
    }

    $attributes['srcset'] = join(', ', $srcset);
  }

  return '<img' . drupal_attributes($attributes) . ' />';
}

You can also feature detect with Modernizr for srcset and retina support, and then swap out the image src with JS shenanigans if you want.

You can also see if the Picture module does what you want, but there is debate in the community about when <picture> should be used and not used.

2
  • This was a bit of a live edit from some working code that did something a little different, and may not work as-is, but will get you going in the right direction.
    – mpdonadio
    Oct 9, 2014 at 18:08
  • Picture module can certainly help
    – Attiks
    Oct 10, 2014 at 6:58
0

I think this module does exactly what what you asked for

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.