I am working on an app where I have to download images from internet and display them inside the app, I am using Universal Image Loader so far, but recently I ran into an issue where the app would not display the images which are huge in size for example 700 x 7661, I have read several posts & answers related to it but nothing seems to be a reliable solution, it appears in an hardware accelerated app the image size is limited by the OpenGL texture size limit, answers here on Stackoverflow suggest resizing the image to smaller size. I know disabling hardware acceleration fixes it, but that is not an option because it makes the whole app jittery.
My question is how can we achieve that accurately because devices have different OpenGL texture limit, some devices support 2048 x 2048 and some support 4096 x 4096, some of them support even smaller, if we resize the image by considering the smallest size the image will appear blurred on high resolution devices, so I am sort of out of clues as how to approach this issue, I have tried Picasso, Fresco & Glide and all of them have similar issue.
A sample of the image I am trying to load is http://i.imgur.com/ADpTC2W.jpg?1
Regards
You can read the device resolution and resize your images as for your resolution
for getting resolution see this : How to get screen resolution
You could look up the maximum texture size by using Canvas.getMaximumBitmapWidth() and Canvas.getMaximumBitmapHeight(), and then resize them before putting them into imageViews.
Related
Working on an Application that displays images in various sizes as grids, lists (Instagram like), images that take up the whole screen.
Ex. - you might have is a grid view image (not very big), but also this same image is shown in another screen that's almost the size of the entire screen. It's like a blown up version of this. There are also the smaller thumbnails of these images.
Working with the Backend team to come up with an optimal solution.
Questions:
What's the most optimal way to handle images for different screen sizes? I know instagram sends the URLs for high resolution low resolution and thumbnails.
Do we need multiple sizes for each image? example. grid view (do we need a 1x, 2x or 3x) for each image?. or can one size serve all phone screen sizes and we can just set the scale mode in code? Would this be ok even for smaller screen sizes? Would this be a poor experience for smaller phone sizes since they need images. To me this wouldn't be optimal since smaller phones like SE don't have the same processing power as iPhone 8 plus.
If we're using the same API to serve iPhone and Android - how can this api be leverage for android given that they have more image sizes to handle.
Any guidance would be greatly appreciate it.
PREMISE:
You are talking about images from web server. Not svgs, not interface
graphics. There's no official documents of this field, just
suppositions and results of experience. I'm sharing mine.
If you meant interface graphics, there are official documentations from Apple and Google. If you meant svgs, they're automatically scaled. If you intended to have answer for those, please edit the topic or open new ones
A solution could be, instead of acting only on images sizes, to change the quality of JPGs.
You can use a full quality ~200x~200 image for little thumbnails (avatars, photo icons), which could be ok for all devices sizes, resolutions and models, without being too heavy.
Then, for bigger previews/full image opened you could maintain the same size (the original one, or a maximum size you define) but, using two version of the image: one with little JPG quality (so that it can be loaded quickly, consume less bytes and show the image content) and the other with the original quality (which requires loading and bytes, but it's only shown by demand).
To choose the right value of the little thumbnail (the ~200px), check the bigger thumb size you have. If you have an avatar bubble which is 96x96 on smallest res, multiply it for 3 (96*3=288) and you have the size!
It is true that the smallest res screen will only require a 96x96 image, but, given that those are little numbers, the difference is not relevant (also, because we are talking about photos and not vectorial images, if you scale manually or if you leave the scaling to the device, the result is the same).
I've found some documentation from Google, which explains some things about image formats and how to reduce download sizes: https://developer.android.com/topic/performance/network-xfer.html
They say to use JPEGs, PNGs, or WebPs and show some examples and guidelines for choosing the right format
You can use svg resources(which is a vector-based-image) : By doing so, you don't need to generate a resource for each resolution, and just need 1 resource. In realtime, the svg image will expand to the resolution of the device.
According to the documentation, you have a lot to gain here :
Using vector drawables instead of bitmaps reduces the size of your APK
because the same file can be resized for different screen densities
without loss of image quality
I have used this in Android, and it solves your issue in Android.
I Haven't used this in iOS but, it looks like there's a similar solution as well.
Your all questions are nearly have same goal. So Basically save 6 versions of images like 50px 100px 200px 400px 800px and 1600px etc.
6 will be enough since you can cover nearly all screen sizes like google does in android. which is ldpi mdpi hdpi xhdpi xxhdpi and xxxhdpi
Use an API for picture requests, send your screen sizes to api as parameter then give back resulting images width and height. for ex: for a 800x600 screen send back 400px version of it.
If you not do so, you will have to resize them on client size which is bad for performance and also bad approach for auto layout in IOS.
You can use third party image managing solutions like Cloudinary.
https://cloudinary.com/
Cloudinary generates images of different aspect ratio which can be serve to all types of devices.
Im having some memory issues with my app. It can pick an image from the users personal gallery and store it in a file to be rendered on the screen. The issue is that the limitation on the imagesize is very small. Which I have discovered lead to pretty much every image on my device being to large to handle. So the method itself became useless since it can't handle moderate sized images. I'm experiencing this only on ios devices so far.
Is there a solution? Can I compress/minimize the size of the image to a smaller one in any way? Cutting all images to the same resolution? (Like Instagram's system).
If you want to reduce the image size in bytes, there are at least 3 areas you can work on:
Reduce image dimensions (pixel resolution). This almost always
causes loss of quality, but if your users are viewing on small
screen devices, and you don't resize too much, the loss won't be
significant. You can also use interpolation to minimize the visual
degradation when resizing.
Reduce bit depth (color resolution).If the image is full color (32
or 24 bits per pixel), you can sometimes get away with reducing it
to a lower color count such as making it 8-bit. Again this will
cause quality loss, but you can use dithering to reduce it.
Use better compression. Most images are
already compressed these days, but in some cases you can re-compress
an image to make the file smaller. One example is JPEG which
supports different quality factors. There are also different
sub-types (color sampling frequencies) in JPEG. So if you save an
image as 4:1:1 instead of 4:4:4, it will contain less color content
and become smaller in byte size, but the difference is usually not
noticeable to the human eye. This post has details on changing
JPEG Quality factor on iOS.
I have a lot of "out of memory" reports in an application from Galaxy S4 users.
The app is working with Bitmap . It has a graphical UI. It works good on all devices but on S4 it crashes.
Do you know if we need any special memory management for S4?
I don’t believe that S4 introduces something out of the ordinary with Memory management or Images. I guess looking at the memory usage of the app will be helpful.. Follow this guide to look at possible leaks and memory consumption of your app.
http://developer.android.com/tools/debugging/debugging-memory.html
Since you said that you deal with images in your apps... In my apps I have had memory problems with bitmaps. A good tip is to use LRUCache to cache and manage bitmaps. Follow the link below to understand LruCache.
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Hope this helps!
In order to solve this, you need to understand how images use memory.
Imagine an image, 800x800 pixels. Without any scaling, this will require approximately 2.5MB of memory. Width x height x 4 bytes.
All loaded images are stored on the heap which is limited in size (there are many discussions on here about heap size).
Now load that image into an ImageView which is displayed on a 1024x768 screen, the size of the ImageView being 800x800 - the same size as the image. You are using DIP as recommended so that your UI scales.
Your 1024x768 display has 786,432 pixels. The S4 has 1920x1080 = 2,073,600 pixels. Approximately 2.6 times as many as the 1024x768 device.
If you do not do anything to scale that image and you do not use the density and resolution "bucket" resource folders, then that same image now needs 2.5x2.6MB = 6.6MB.
The key point is that unless you control it, your image will use
different amounts of heap memory (which is limited, it doesn't matter
how much RAM the device has) on different devices.
I suspect that your app would have problems on Nexus devices too.
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
http://developer.android.com/guide/practices/screens_support.html
I have question that is connected to display images on android devices.
I have many png files that I want to display and they have got 1024 x 768 resolution and have text in image. The text in images must be readable - this is important thing. Because png it is bitmap format I understand that the loss of quality is inevitable. Maybe some one can advice me to choose some approach to solve this issue. Maybe I have to choose just devices that can display those images.
All images like this below:
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.