Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: pixel quality reduction in Images loaded in WebView

I am building Javascript application for mobile browsers (not wrapped-as-native app).

I noticed that Android (tested 2.3 emulator and Galaxy S device) reduces the quality of loaded images if the image dimensions exceed certain threshold (width above 1400 px or so). This make it impossible to load big bitmap images (2000 x 2000 px) without the quality going unusable.

I tested this by

  • Loading one big image and drawing it on the - I got pixel garbage out. If I draw grid lines using lineTo() on they have perfect quality, so the bad must be in the image pixel data

  • Slicing the big image to 100 x 100 slices and drawing them to a canvas - this is the only method I found resulting no quality reduction. However, slicing is cumbersome, adds extra step to preprocess images and page loading times suffers

  • I tested tring to load image with new Image() object, tag and CSS background: everything suffers from the reduced quality, so I suspect the probelm is the image loader itself

  • I also tried everything with CSS image-rendering https://developer.mozilla.org/En/CSS/Image-rendering - no luck

  • Viewport tag seems to have no effect to the image loading - the data is already garbage when you try to touch the loaded pixel data. I tried all possible values suggested in Android's SDK documentation http://developer.android.com/reference/android/webkit/WebView.html

Tested also Firefox mobile, desktop browsers, iOS: everything is good there.

So, what is going on - Android WebView simply can't load big images?

(smiley of hung Android robot here)

like image 259
Mikko Ohtamaa Avatar asked Jul 09 '11 01:07

Mikko Ohtamaa


1 Answers

Android unconditionally resamples images and reduces quality if a certain threshold of memory usage is exceeded.
https://android.googlesource.com/platform/external/webkit/+/android-3.2.4_r1/WebCore/platform/graphics/android/ImageSourceAndroid.cpp

There is no way to access the original image data in intact.

I posted a question regarding this to android-developers Google Group and kindly asking to maybe provide some kind of flag to opt-out from this behavior.

Meanwhile, if you are considering developing HTML5 web apps and you might use big images, you simply need to preprocess them on the server-side by slicing, send in smaller images to the device and then reconstuct the original image using or putting many tags inside a container element.

Another option would be load image "manually" by writing a PNG decoder which directly loads the image to , bypassing ImageSourceAndroid class.

like image 143
Mikko Ohtamaa Avatar answered Nov 13 '22 19:11

Mikko Ohtamaa