While doing some homework this evening on how to best display Retina-resolution photographs on the new iPad for future updates to both this and the Luma Labs sites, I ran into a frustrating problem. Relatively small high-resolution images—such as John Gruber’s Daring Fireball logo—work great. But 2000-pixel wide photographs failed miserably and ended up looking worse than the 1000-pixel wide images they were replacing in my test pages. Much worse, in fact.
I finally grumbled about it on Twitter, got a few responses from some friendly people, and then it got interesting. Steve Streza pointed to his Quora post on adding 2x images to webpages. I showed him a sample image that was failing for me, and in the back and forth, we got somewhere. Turns out that above a certain size, WebKit is deciding to scale down the resolution of images.
What’s that size? Good question. I started narrowing it down and found the transition happened between 1775 and 1776 pixels wide on my sample image. Steve tried on his end and didn’t see the same thing, so I started narrowing down the height. At the same time as I found that the scaling kicked in at between 1180 and 1181 pixels high, Steve tweeted a hypothesis that if an image contained more than 2 * 1024 * 1024 pixels, it would be scaled.
A bit of quick math on the back of an envelope: 1775 * 1180 = 2,094,500.
1776 * 1181 = 2,097,456. And of course, 2 * 1024 * 1024 = 2,097,152. Right in between. With a nice geeky number like that, it seems we’re dealing with is a hard limit set somewhere. But where? At what level? Hardware? Software? After all, photographs from the iPad’s internal camera are bigger than this and the iPad deals with them just fine.
Well, this is where it gets weird. If you feed WebKit a PNG image that’s bigger than the limit above, it displays just fine, thank you very much. It’s a bigger download over the wire—much bigger in fact and you wouldn’t want to serve up big photographs this way in production—but WebKit turns ’em around and tosses ’em up on the screen with nary a whine. That seems to indicate a premature optimization in WebKit’s JPG handling on the iPad.
You can see for yourself on this simple test page. If you go there with a desktop browser, the first three greyscale ramps will look the same size. But go there with a new iPad and you’ll see the issue with the with the slighly larger JPG being scaled down. To see the problem with a real photograph, here’s a test page that uses both images and divs. Divs are included as they have been a commonly suggested workaround that doesn’t work in this case. On an iPad, you’ll notice the 1775 pixel wide images look Retina nice. The 1776 pixel wide images are rescaled to half the resolution and don’t look nearly as nice.
Now, it does get a bit stranger even. Digging around Apple’s iPad pages, I found the big hero image they use is 2240x960. That’s 2,150,400 pixels, which is bigger than the 2 megapixel limit above. On the other hand, as @thijs notes, those dimensions are evenly divisible by 16. Furthermore, the iOS web content limitations (also dug up by Thijs after I first posted this, and yes I did go looking for it before I started Tweeting but failed to find it) talk about a 2 megapixel JPG limit, a 3 megapixel PNG/TIFF/GIF limit, and a 5 megapixel canvas limit and indicate that larger JPG images are subsampled. But, how those rules fit together with what we’ve seen—including the big iPad hero JPG image which is definitely larger than 2 megapixels but which doesn’t look like it’s being subsampled—is still a bit unclear.
Bottom line, however, is that there’s a limit to serving up web images in JPG format with WebKit the new iPad and the limit kicks in when you approach screen-filling resolutions. Hopefully, a future update can lift the limits just a bit so that it’s possible to display full-screen images in Safari that look as great as full-screen images do elsewhere on the system.
By the way, Steve filed a bug with Apple about this. It’s rdar://problem/11097671 for those of you that can use that information.
Update: Apparently, the iPad hero image uses a progressive JPEG file and @radiofreejohn confirms that my sample images turned into progressive JPEGs work.
Update 2: Indeed. Progressive JPEG is the trick. Check out my example of it in use.