DPR on images without explicit sizes?
Hi,
I'm working on responsive images for our blog, trying to construct Cloudinary URLs for `srcset` (I have explored other options like client hints or your JavaScript library). I got quite far but don't know how to overcome the final challenge with high-DPI (retina) screens but let's start from the beginning:
Images in our blog posts are usually stored in Markdown like this:
```

```
My code extracts this URL and produces a set of source URLs, each of which has different width injected, like this:
- https://res.cloudinary.com/demo/image/upload/w_200/sample.jpg
- https://res.cloudinary.com/demo/image/upload/w_400/sample.jpg
- ...
- https://res.cloudinary.com/demo/image/upload/w_1000/sample.jpg (this is our widest layout)
This works great for full-width images, like in this blog post, but it upscales smaller images. Fortunately, there is `c_lfill`, so I can do this:
- https://res.cloudinary.com/demo/image/upload/w_200,c_lfill/sample.jpg
- https://res.cloudinary.com/demo/image/upload/w_400,c_lfill/sample.jpg
- ...
- https://res.cloudinary.com/demo/image/upload/w_1000,c_lfill/sample.jpg
So far so good but now I'd like to add retina support (x2 only to keep it simple), so generally, I would continue up to 2000 instead of 1000. `sizes` inside `<picture` stay the same: if the browser sees a suggestion to use 1000px wide image, it will fetch 2000px retina image on browsers with DPR = 2.
Now comes the problem. The image fetched will be this:
https://res.cloudinary.com/demo/image/upload/w_2000,c_lfill/sample.jpg
which is still limited to its natural width, which is 864px in this case. The problem is that after downloading this image, the browser will render it half the size, probably because it converts "real pixels" back to "CSS pixels".
I tried this but it doesn't have any effect:
https://res.cloudinary.com/demo/image/upload/w_2000,c_lfill,dpr_2.0/sample.jpg
For comparison, if width is set explicitly and there is no `c_lfill`, `dpr_2.0` does the right thing:
https://res.cloudinary.com/demo/image/upload/w_300,dpr_2.0/sample.jpg (the width is actually 600px)
For another comparison, if the width is not set explicitly, `dpr_2.0` has no effect again:
https://res.cloudinary.com/demo/image/upload/dpr_2.0/sample.jpg (width is 864px, not 2*864)
Is there a way to make Cloudinary images with with `dpr` and their natural widths?
-
A couple of notes:
- Our source data doesn't contain information about how large the images are.
- We'd like to avoid making API requests to query this information. We use a static site generator that would issue many API requests over and over, which is a waste.
- There is this related topic about conditional transformations, however, we don't know the exact size ahead of time: https://support.cloudinary.com/hc/en-us/community/posts/115003192591-Prevent-upscaling-responsive-images
-
In order to understand your use-case better can you please provide more information about it?
If you want to upscale your image you can either use CSS with width 100% or with cloudinary your can either use w_1000 and dpr 2.0 or w_2000. however, when taking a small image and upscale it, as a result, we will get stretch and blurry image that will produce more storage and bandwidth.You can add the width as initial width w_iw but It will just stretch it:
https://res.cloudinary.com/demo/image/upload/dpr_2.0,w_iw/sample.jpg
-
Thanks, Shirly, I didn't know about w_iw.
To repeat the use case, my question is that if I have just this URL:
https://res.cloudinary.com/demo/image/upload/sample.jpg
then if it's possible to construct a set of Cloudinary URLs that will downscale the image for smaller devices but won't upscale it above image's natural width.
The key point is that I don't know the width ahead of time. For example, that "sample.jpg" happens to be 864px wide but I don't know that when constructing picture and scrset. The problem is that if I mechanically add a source like
https://res.cloudinary.com/demo/image/upload/w_1200,c_lfill/sample.jpg 1200w
this will cause all sorts of trouble (I'm "lying" to the browser – I say with "1200w" that it is 1200px wide but the actual URL will only return 864 pixels horizontally).
I guess it's just an inherent problem of my use case, maybe Cloudinary's JavaScript library does some clever tricks that don't force me to know image width ahead of time?
-
Have you tried our javascript option as described here:
https://cloudinary.com/documentation/responsive_images#automating_responsive_images_with_javascript
I created a jsfiddle for you to try:
https://jsfiddle.net/shirlymanor/86vbk0fn/
Please let me know if that helps,
Please sign in to leave a comment.
Comments
6 comments