I am developing an application for android and it contains several images and I have to get them from drawable, so I am using bitmap for them to avoid out of memory exception by rescaling them, but the problem is when rescaling, the resolution (/quality) of the image is reduced. How can I overcome this problem?
You can keep a reference to the original byte array and check your bitmap size against it but I would just use pngs in the appropriate drawable folders. Rescaling/reloading the image yourself and checking for quality could be much more memory hungry in a garbage collected language.
Let android do it's thing..
The only way you can avoid the loss in quality is by scaling the image proportionately in terms of width and height.
For eg : if your resolution is 100x80 try reducing it to 5x:4x . That will somewhat preserve the quality.
Related
I am using 10 png images of size 20-30kb in imageView, but the allocated memory increases from 70mb to 270mb when this activity loads.
So why this too much of memory is allocated to these images.
This is the screenshot of memory allocation
This is one of my image
File size doesn't matter. No, matter your image is of 20kb but its resolution is quite big. When image is loaded into memory it takes memory equal to totalNoOfDotsInImageBitmap * 4bytes
and totalNoOfDotsInImageBitmap = width *height of image.
4 bytes - because of ARBG ( 1 byte per argument) for single dot of bitmap
so reducing width and height of image may solve your problem.
Depending on where you are putting the assets it may be trying to load a file that is too large.
For instance, if you have it on drawable or nodpi-drawable a device with a low density will try to load a potentially large image.
Also, bear in mind that the actual file size is not that important as it is probably small due to compression, but the image has to be converted to bitmap when it gets drawn, so if the actual size is too much that can also cause an OOM.
If you have access to the original I would recommend using a vector drawable (it's a simple shape so should be ok) and AS will generate the required PNG files for older versions.
I'm taking whole screenshot of a WebView and display the bitmap on an ImageView. The bitmap can be 7 screen height. (E.g. 1440x14000 px)
I'm frequently face with
OutOfMemoryError.
I've seen this
This says that load a scaled down version into memory but I don't want to lose image quality. There are the same approaches on the web.
Is there any way to handle OutOfMemoryError without loading scaled down version?
The bitmap can be 7 screen height. (E.g. 1440x14000 px)
Note that this means that the user cannot see the whole image at once at full resolution.
I'm frequently face with OutOfMemoryError
On most devices, you will have a very difficult time loading an image that large, as you cannot get a single contiguous memory block that big.
This says that load a scaled down version into memory but I don't want to lose image quality
To some extent, you do not have much of a choice. If you want the user to see the full extent of the picture at once, the image has to be scaled to fit the screen.
Is there any way to handle OutOfMemoryError without loading scaled down version?
There are ImageView replacements that offer pan and zoom. Some of those, such as this one, handle loading in pieces of the image at a time, with whatever scaling is necessary for the current zoom level, to make it more likely that you will be able to show the user the entire image.
It is not a solution, of course, but I'm also not familiar with your exact needs, so maybe this may help you a little - you can try to play with bitmap options during decoding. Try to use Bitmap.Config.inPreferredConfig as RGB_565 - this will reduce size of your bitmap twice comparing to default ARGB_8888. But, of course, if you use complex images in your web page this may reduce their quality.
I'm currently facing several performance issues (out-of-memory) when handling a vast amount of bitmaps. As this is just a problem that can be fixed I'm wondering if anybody can explain me the difference in using the following methods.
If I only want to load an image into an ImageView I usually use:
imageView.setImageDrawable(getResources.getDrawable(R.drawable.id));
If I want to sample the drawable beforehand I usually use (here without sampling):
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.id);
imageView.setImageBitmap(bm);
My question is related to performance optimisation. I'm wondering whether it is better to provide as many drawables as possible using the different drawable folders (so these drawables nearly fit the required resolution for the different devices) or if it is better to sample high-quality drawables? What is setImageDrawable doing internally? Does it decode the resources using the BitmapFactory, just without sampling? There seems to be a trade-off between the actual size of the app and the cpu- and memory-load during runtime.
if you're concerned about apk size, then having as many drawables as possible is not the ideal way to go. but dont forget, when you decode a bitmap, you can pass a sample size so it will scale down to the screen size and only give you the pixels you need, so older phones with smaller screens wont need to decode 8mp images.
check BitmapFactory.Options and here
Looking to resize six images I download from the size of 1200x1200 to just 1024x1024 without having the outOfMemory error.
So far using the Bitmap.createScaledBitmap(src, dstWidth, dstHeight, filter) cause the OOM problems. and scaling it using the BitmapFactory.options and specifying the inSampleSize best can get me is 600x600 size image.
Is there any solution to scale the images to exactly 1024x1024 or there isn't ?
and a general question why we always have Bitmap problems in android can't they fix the garbage collector to collect all unused bitmaps ?
Where is the picture located? If it's inside the mdpi folder try to put it inside the hdpi or xhdpi. This solved my problem once. I guess Android also tries to resize the image so this causes out of memory errors.
My application use a little memory, it's about 3.4MB, in some old android devices such as GT-I9001. But when i running it in HTC one, my application use very more memory.
Look, the allocated memory is 26.881MB, it's too big, and the free memory only have 2.940MB. Then i use MAT tool check the memory leak, i find the resource bitmap use mach memory.
I can't explain the reason. My application often out of memory. I think Maybe the problem is caused by high screen resolution. If someone also encountered this problem, please join the discussion, thanks!
I debuged the problem, and found some reason:
The onCreate() function in my start activity, and you can see the breakpoint. The application only use allocated memory 3.4MB before calling the setContentView(R.layout.welcome) to load layout xml. Then the application run to next step, it use allocated memory 19MB. So i think this problem must be caused by loading the layout xml.
I modifed the "welcome.xml" file, deleted all widgets, that only have a "RelativeLayout"
But the program also use 19MB memory. Finally, i deleted the backgroud of RelativeLayout and the program memory return to normal size, it only use 3MB.
The size of pictrue "loading_background.png" is only 21KB, i think that perhaps the high screen resolution of high-end device changed the picture size in memory, i will try to use 9.png picture. If you understand this part of the problem, please join the discussion, thanks!
It's not a memory leak if you use big image for background.
File size doesn't matter. When it is loaded into memory it takes width * height of the image * 4bytes.
Use small 9-patch images or shape drawables when possible.
This problem can be solved using drawable-nodpi, look this:
Android background image memory usage
Just try to make a bitmap from 3MB PNG file. You will get a 20MB picture. That's why it's beter to convert your images from PNG to JPG. The quality is not so much different actually, but you will profit a lot from memory side.
just add high resolution images to the xxhdpi folder in drawable. this prevent android scale up the image to the ultra sizes