Hacker News new | past | comments | ask | show | jobs | submit login

As high DPI displays become more common, it seems like the time has come for more advanced file formats (or just using the more advanced features of existing formats). For example, PNG already has an interlacing mode that progressively adds detail to the image (http://en.wikipedia.org/wiki/Adam7_algorithm). It could easily be co-opted such that a normal image contains 6 layers of detail, with an additional "retina extension" image that high DPI browsers grab to refine the quality. This avoids the waste of downloading a low DPI image, then throwing it away to replace it with high DPI.

Even more interesting is http://en.wikipedia.org/wiki/JPEG_2000, which has "truncatable" bitstreams. You can stop getting data at any point, and depending on the encoding choices, you'll just lose fidelity in colour, resolution etc. Encoders can reorder the bitstream to deliver whatever is most useful for the image first. Browsers could then just stop when "enough" has been downloaded to satisfy the demands of the device; high DPI devices would just continue to grab more of the bitstream. It's really useful for devices on low bandwidth links, as you start getting visual results with very little data.

JPEG 2000 hasn't been widely implemented outside of specialised devices, mostly because it's computationally heavy compared to JPEG, and the patent situation is unclear. Although this does mean that it could be implemented in a targeted way, designed to solve these problems (the spec for the entire format is huge). Moreover, one of the patent holders is, IIRC, Apple.




The idea of compound images is really interesting, although it would require an extra HTTP request to fetch the hight-DPI portion of the image. But maybe less of a problem over SPDY?

The idea truncatable bitstreams is fascinating too. I'm not well versed in networking, but wouldn't the latency of a mobile network kill the benefit of this technique? e.g, by the time the server receives the "connection closed" signal, a large part of the extra data would have been sent, no?


It would need an extra HTTP request, yes. In practice for the PNG solution, one would be better off with sending the DPI in the request headers, so that the "correct" image is the only one sent.

For JPEG 2000, the network characteristics are important, but I don't think it would be too bad on a mobile network. Low DPI devices might get a bit "too much", but it wouldn't be a problem - they can just throw it out (or incorporate more detail).


Headers do seem the best place for a non vendor specific standard to be set. I'd love to see something like

viewport-dpi - the dpi viewport-max - the maximum possible pixel dimension and possibly viewport-current - the pixel dimensions at the time of the request

Decent responsive design should deal with the differing viewport sizes, but it might be nice to get a hint before delivering your page what direction to weight that response in.


What do you do when using a projector, and your DPI is something like 3? (serious question, I don't know how this is traditionally handled)


Something like device-pixel-ratio would be more useful than DPI. Raw DPI is meaningless unless you take distance into account, as is very clear in the case of the projector.


Would this work better over WebP?


Check this way of doing it to avoid extra http requests. http://www.archer-group.com/2012/development/javascript-jque...


That is certainly the ideal way to reduce the HTTP requests. The problem with this implementation is clear: without a 'src' attribute on your images, if your script fails then your site suddenly has no images at all. Not to mention the overhead of manually modifying all of your existing markup.

Our goal with retina.js was to make it zero-config: no markup changes, no extra element attributes or flags.


The Stripe gallery posted here the other day[1] used src-less img tags for lazy loading. It looks like they handle the script issue by having the normal img tag (with src attribute) nearby in a noscript block.

Doesn't really do much to help with the overhead of modifying existing markup. Perhaps if you're already using something like image_tag in Rails, a retina_image_tag helper might not be too much of a stretch.

1: https://stripe.com/gallery


Sounds complicated. I think we just need to do something similar to HTML5 'video' tags for the 'image' tag, where you simply put a list of file paths in the tag, and the browser selects the best one to request, only with different resolutions instead of different file encodings. We could have a standard notation like adding "_x2" to the double res image filenames, and the browser selects the appropriate one to load.

Then, we can support current image formats in the way you envision.

Also, anything you have vectorized should be in SVG format, including text in non-web fonts.


That's fine if a) you're willing to maintain two image sets and, b) the only two resolution images you need are "normal" and "2 x normal". The advantage of a progressive quality system is it scales to arbitrary requirements in a single resource. One file provides 1x, 2x, 3x, 3.14x etc.


Storage is too cheap to care these days.

When $110 buys you 2TB (this morning on Newegg), then doing it on the fly and caching the result has about 100x better ROI than trying to solve it with a smart format. Remember, we're speaking about still photos here, where high retina quality ones rarely take more than 500k each, so 2TB buys you room for 4,000,000 photos (and since you'll be caching the lower res 200K images, it actually buys you room for 10,000,000 million photos)

That's not the case for videos - netflix, hulu and friends have multiple copies of each 1GB optimized for different devices. On-the-fly conversion is not possible, and the stream are significantly difference. For them, a reasonable, universally supported progressive video format will indeed make a huge difference


I don't think archgrove's point was about storage, but about the extra friction of tracking N files instead of 1.


That might be, but with the right Apache, nginx, varnish (take your pick) module, this friction will be reduced to saying something like:

    lower_res {
      Request /lowres/*.jpg
      Provide /highres/$1.jpg
      Downscale 50%,50%
      Cached_on /mnt/cheapdisk_that_can_go_away_at_any_time
    }
I'm not aware of such an existing module, but I'm sure a good one will appear within the next couple of years of it does not yet exist.

Compared to developing and deploying a new progressive format (across users, web servers and web browsers), the effort -- both in developing this module, and in configuration, is negligible.


Problem with new formats is legacy support. Something that could degrade gracefully on browsers that don't add support would be very welcome. Maybe the best solution is to keep the current 'img' tag notation, but somehow indicate to browsers that double-rez assets are likely to be available at something like 'filename_x2.ext', and they should request those when they come across an img tag, instead of 'filename.ext', falling back with a second request for the latter in case the '_x2' isn't found. Something like:

  <meta img-x2-res="_x2" />
Encoding the image twice with a standardized addition to the filename is just an extra bit to add to the export macro. The image storage is irrelevant for most cases (assuming you compress appropriately); it's the bandwidth and request volume that's precious.


If you are going to do that you may as well have a meta tag to set a suffix "to find the jpeg2000 version of the image", and browsers that understand that format can then get the better format.


Not a bad idea. The meta tag should be made our bitch, so we don't have to work so much, and our sites can degrade gracefully.


In fact, something very similar to what you describe is what's being implemented right now: https://bugs.webkit.org/show_bug.cgi?id=80322

I'd like to propose a new function for the Images module. This function will allow developers to provide, in a compact manner, multiple variants of the same image at differing resolutions. Using @media pushes the two asset references apart from one another, whereas such a function keeps related asset references together. It also helps keep selectors DRY. We've called it image-set(), and it takes one or more image specifiers.


Wow, not only does that notation seem like a huge pain in the ass, but it's only for CSS; doesn't fix the html.

https://plus.google.com/115203843155141445032/posts/BrrLGL5k...

  -webkit-image-set( url(image.png) 1x, url(image@2x.png) 2x )
That's their notation. Imagine having to do that for every image ever, when they're all just filename + 2x resolution key + filename extension. Totally asinine. Developers should just be able to pick a single page-wide filename key for all their 2x assets, and the browser will know to look there.


Yep, a solution is still needed for content images.

That's their notation. Imagine having to do that for every image ever, when they're all just filename + 2x resolution key + filename extension. Totally asinine. Developers should just be able to pick a single page-wide filename key for all their 2x assets, and the browser will know to look there.

You assume the developers can guarantee all image assets will be 2x. For quite some time, I doubt that'll be the case. And, given that, if the browser just naively requested 2x assets, there would be some set of wasted http requests that just add overhead and significantly delay page load.

Explicitly declaring the 1x and 2x images' existence is a far better solution, even if it is more verbose. The UA can't be guessing about the existence of resources if it's also to be efficient.


No, the better solution would be to add support for:

  <meta img-x2-res="_x2" />
This would alert the browser of the likely presence of 'filename_x2.ext' when it sees img tags, and it would fall back with a second request for 'filename.ext' in case it's not found. This seems relatively easy to implement (especially for web developers), and degrades gracefully on older browsers.

Then, a more fleshed out version accounting for the scenario you describe would be the following:

  <meta img-x2-res="_x2" assume-present="false" />
Then for any img tags for which double-res assets are available, you could add a property to the img tag as such:

<img x2-res="true" />

Or, you could leave the 'assume-present' property off, as 'true' is default, and put '<img x2-res="false" />' on any images for which double-res assets are unavailable. This would avoid a second request when the first fails.

Such a solution would be significantly more convenient for developers, as you could choose whether to assume the presence of 2x and flag ones that don't have it, or assume its absence and flag those that do, saving tons of time.


Sorry, that should be '2x', not 'x2'. The img '2x-res' property could also be used to provide an asset-specific 2x-res filename key as such:

  <img 2x-res="@2x" />
If we wanted this to affect the image asset requested by the CSS background-image and border-image values as well, then a new CSS property would be required for flagging 2x-res active or not and an asset-specific 2x filename key. But its use would be vastly superior to -webkit-image-set, as you could just do this:

  .class {2x-res: "@2x"}
or:

  .class {2x-res: "false"}
The only limitation is that these 2x assets must share the same filename with the 1x, except for the addition of a 2x key at the end of the filename. However, that seems to be what people are already doing simply to keep track of their assets, and it's much easier to sell me on this imposition than on having to redo all my CSS in the most redundant and painful way imaginable.


Regarding the first trick: the value really isn't very much. Storing 2x2 downsampled versions of an image at all levels is only a 33% increase in size. This is the mipmap trick, and can be done right now with nothing but a size check on the client. I don't think 33% is worth mucking with file formats over.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: