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)
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.
The question is old so probably few things changed, but if you are having image quality issues with WebView then consider converting your image into PNG format.
Somehow when I load the jpeg version of the image the quality is low, while loading the png image with the same resolution the quality is high.
Related
So, we are using Fresco in our android app and so far it has been great. There is one issue that we are seeing when we load an image of size 8000x4500. We are seeing a Jank when that image is being loaded in the list on all devices and on some lower end devices, we are getting an OOM error (which is ok because we were testing on a 80$ device which is low on resources). Not sure if we are doing anything wrong or missing something.
In our app all images are encoded as DataUris (conforms to RFC 2397) and we are loading the images using setImageURI method.
Now my question is, does the conversion of URI to bitmap inside Fresco happens on the same thread or does it happen in a background thread? I was trying to browse the code and understand it myself, but understanding the control flow wasn't straightforward. In particular, I couldn't figure out how the mTopLevelDrawable is updated for ImageRequest of type DataUri.
Any help on understanding how it works, what could be done at the application level to prevent it would be great.
We are ok to set a maximum dimension to something like 1280 or the width of the window. Would that help reduce the decoding time?
Thanks in advance!
Note : We deliberately choose a high resolution image to understand the limits of our product. For regular sized images, things are pretty smooth. For high resolution images, even on higher end devices like pixel 4, there is a jank.
I am making an app and part of it will view PDF's. The pdf's are on a web server and downloaded to the app. I am trying to understand what happens when a viewer loads a pdf. If it is converted to an image then I would like to try converting the pdf to a png on the server and just using that copy to view in app as png is a lot less hassle to deal with.
The only reason I would not convert to png is if an android pdf viewer maintains the vector nature of the file as zooming is critical and I want a nice crisp image.
Ultimately someone is always going to convert the PDF to an image. Or better said to pixels because that is what you need to display on the tablet screen (or any screen that I know of). The question is who does the conversion, when it is done and how well and quickly it is done.
For a tablet viewer, the challenge is to do the conversion quickly enough not to bother the user with load times and that often goes at the price of quality. There are virtually no PDF viewing applications on either iOS or Android at this point that do a really good job at showing all intricacies of the PDF file format.
That being said, the quality is usually good enough and if the viewer is well implemented, zooming for a PDF file should be a no brainer. Zooming simply means for the application that the viewport (the part of the PDF page that is visible) is different, but it doesn't really change the algorithm used to convert the PDF page elements into pixels.
That is also the difference between you converting the PDF to an image on the server and the app converting it to pixels on the device. Your server likely has more calculation power (at least it might have :-)) but the application knows at which resolution it needs to convert to pixels and what part of the page it has to convert to pixels. And a good viewing application can use these details to adapt how it does the conversion to pixels. There are lots of optimisation algorithms that can be used to only render visible elements and take shortcuts based on knowing exactly what resolution will be used for rendering.
In short, yes, you can do the rendering on the server and feed an image to your viewer. But keep in mind that - especially while allowing the user to zoom - you'll get lots of data and probably poorer quality than when you let a good viewer handle things in PDF...
I am into developing an android app which fetches images from server. A single activity downloads more than 10 images from the server. So, what should be the size of images(in bytes) so that the app runs smoothly and swiftly?
It is not the size of images that really matters..its the resolution of the image that really matters. When you try to take that image to a bitmap variable, the memory is consumed to represent each pixel of your image. Since you are working in a client server scenario, the size will become a problem when it comes to download and store the image.
If you don't need to zoom the image in your application, it is better to use image with standard resolution that matches screen size.
Its better for you to use some image manager libraries for these kind of image loading purpose, so that they will manage the memory issues to an extend. Check this post.
I am building a simple wallpaper app. I store the wallpaper images(.jpg) as resources in the res folder. I show the user a grid of thumbnails, which I store separately as resources(.jpg) too in res. I want the scrolling through this grid to be smooth and fast. My question is that when I load the gridview using the adapter, In the getView method I convert the resource to a bitmap and then load it in each imageView in the Grid. Would it be faster if I stored the thumbnails as .bmp in the res folder in the first place? Also I've manually created the thumbnails, rather than manipulating the large wallpapers making them at run-time. Each thumbnail is made to scale to width of 120pixels and the grid consists of 120x120 imageviews. So I was wondering how I could load these images quickly and effectively?
Im setting the adapter to the gridview inside Asyntask, but I dont notice an improvement.
Jpeg, which is lossy image compression, usually provides the best quality to size trade-off.
If you're trying to store high quality images then you're almost certainly going to want to use Jpeg.
PNG does has useful features such as allowing you to work with transparency, and, for simple block colour images outputs really small file sizes.
However, the moment you start to create photo quality images, such as wallpapers, as PNG, you're going to see monster file sizes, which on a mobile device is not going to be much fun or much appreciated by the end user.
Also larger files tend to require more system resources (CPU time and RAM), and on a mobile devices these resources are at a premium.
I would suggest that perhaps for thumbnails you might use PNG, and for the full size image use JPEG, but you might do well to see which creates the smallest file, because that is likely to give an good indication of the rendering efficiency i.e. it takes little resources to render a 800b PNG.
Changing your images to the bmp file format could make a little improvement in performance (because JPG is a compressed bitmap image that needs to be decompressed when rendered), but it's usually not worth the major increase in filesize.
I would recommend using the PNG bitmap format because it's light in both rendering and filesize.
As for the rendering in the ListView, you might want to take a look at this question and this code project.
I'm developing a mobile web application and I have a home screen with a number of icons on it, so I tried to use a sprite to serve all the images in one swoop.
I noticed, however, that the iphone4 scaled the images in my sprite fairly well (they looked a little dithered), but on my HTC Evo the sprite rendered images look really blocky. I switched to standard images (background:(/image_url/) w/o background-position) and the image looked much better - see this , where the left image is served using the single image, and the ones to the right of it are served from the sprite (but are the same images in the sprite).
Is there a way to get the Android browser to interpret the sprites better?
You're hitting the maximum decoded image size barrier in the Android browser. This size limit was upped to something reasonable in 2.3. Try splitting up your sprites into smaller images.
This is just a guess but, which one are you using? Your operator or wifi connection? Some operators do compress images over certain size.