I'm making a game for Android and I'm using transparent PNG's. But does the transparent part take up large memory?
For example if I have a PNG that is 512*512 that is transparent, does that take up the same amount of RAM and or ROM as one with 256*246??
//Simon
The size depends entirely on the pictures resolution when beeing uncompressed in memory.
If you have pixel with transparency (an alpha-channel), you are most likely using ARGB8888 as the image format. With this each pixel takes 4 bytes in memory. Which means the 512x512 pixel image takes (512*512*4) bytes = 1 MB and the smaller on (256*246*4) bytes = 246 kB.
If the pixels are transparent (invisible) or not doesn't matter. Only resolution and internal format are relevant.
When your image is loaded into the memory it will be a bitmap, no matter what the original format on the disc was, so it really depends on what Config you load your image with.
If you load your image as ARGB_8888, every color component of every pixel of the image will take up one byte, i.e. the alpha (transparency) will take up one fourth of the total image memory and every pixel will be 4 bytes.
An image that is 512x512 pixels with transparency will take
about 1048 kB memory.
Without transparency it will be 786kB.
There isn't any RGB_888 colormode, the closest is RGB_565, which
would be 524kB.
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 am using a button with a png background for CopyToClipboard function in my app (used about 6-7 times in various fragment). Since the image should be small for my purpose, I increased the area of my image by putting in extra transparent area around the image so that I could increase the button size for clickable area but keep the image small (I know its not efficient and since then I have devised better way to achieve this).
I noticed the huge spikes later on afterwards when uploading some other images (big images about 150kb size), and after a lot of debugging (and I do mean a lot!) I found that the problem was not due to the bigger images but due to the CopyToClipboard image which was of just 8kb in size!!! Changing back to older CopyToClipboard image (having lesser Transparent area) brought the memory consumption back to normal.
My question is why did that happen? For such a small image to create such huge spikes (more than doubled the memory consumption from previous) and made the app slow, is quite baffling.
Image shown below : The White area is the transparent area. My button dimension : 15dp x 15dp .
I repeat, My question is why did that happen? Not a solution for it since I already solved the problem.
It doesn't really matter that your image is only 7-8KB on disk, because it will take much more memory when it's decoded.
Apparently, large transparent area can be efficiently encoded in PNG file, so the image has that small size.
But in fact, it's dimension is (600 x 745), so in memory it will take roughly (600 * 745 * 4) bytes, plus some meta information, so nearly 2 megabytes. 4 multiplier stands for an amount of bytes needed to encode color with alpha channel.
Android Bitmaps are represented internally by linear one-dimensional array of integers, so you can imagine that system needs to allocate an array with size 600 * 745 = 447000 to create your Bitmap.
That's why memory consumption is so high for such a simple image.
In the attempt of performing animation with large set of images, I tried with FrameAnimation but I found of outofmemory exception with large set of images, after some exploration for the solution I found one good solution here Pinhassi's solution.
This one helps me to achieve animation but not smoothly because it taking a time to load the images. Then I decided to decode bitmap before starting the animation (giving bitmap instead of resID to ImageView). Through this I got smooth animation. But it is taking a time to decode the bitmap from the resources.
Is there any better approach to do the same? Any suggestion would be appreciated.
Details of the image
Total Number of images =30;
Image Dimension =1000x 720;
Size =180kb
Devices on which I am performing
Manufacture: Motorola
Model: MZ601
Android Version: 3.0
To decode Bitmap
Bitmap mBitmap=BitmapFactory.decodeResource(getResources(),resID);
int bitmapSize= mBitmap.getRowBytes()*mBitmap.getHeight())
The approximate bitmapSize values is 3000000 (might be it is in bytes) converting it to kilobytes 23437.5kb
Here original png file is 180kb but after decoding it, taking nearly 2MB of data. Why?
Is I am doing anything wrong in analyzing the size of bitmap?
If yes, then how to get the size of decode bitmap?
If no, then any one explain why it is taking large space?
Note: I don’t want to scale the bitmap since it is perfect to my device screen dimension which is (1280 x 752).
Thanks
In advance for valuable suggestions and solutions.
Here original png file is 180kb but after decoding it, taking nearly
2MB of data. Why?
Assuming 1 byte per pixel with three color channels(RGB) Byte size = 3X(1000X720)/(1024*1024) = 2.05 MB approx.
There is a limit such processing can reach with plain bitmap loading, that's why Video codec's exist.
I have a frame animation with 135 frames that should swap 25 times per second. The frames are 700X1000 pixels with 240 dpi. The problem I have is that whenever I define in the XML animation file more than 5 frames the application crashes. The frames are found in the drawable folder. I tried copying them to the drawable-xhdpi but this did not solve the problem.
Thanks,
Simon
Problem that loading images consumes all heap memory (memory that has your application avaliable) which is 32MB or 64MB. Images are loaded in on heap as Bitmap in ARGB - 4 bytes per pixel. Try to subsample animation images. Your animation has 135*700*1000*4 bytes = 360.5 MB.
You can use method decodeResource with BitmapFactory.Options opts that has parameter inSampleSize where you can set subsampling of image. Also parameter inPreferredConfig can be used to set RGB_565 instead of ARGB_8888 in case when you don't need transparency in images.
The error clearly says that you are trying to use more memory. This directly points to the image sizes. So, you need to resize your images to use lesser memory. One which can be used for this reason is BitmapFactory.Option. Or else go with manually resizing your images take care that it suit all your needs.
Heap size is the amount of memory allocated to an application to
execute.
The heap size for android applications are determined by the device
RAM. For example if the device has RAM of 179 MB, the android
applications will only get the heap size of 18MB.
Find about it more here. more on how to Load Large Bitmaps Efficiently is found here.
As the stack trace says, it's causing OutOfMemory error.
Since the frames are with higher resolution and no.of frames are also more, it's giving this exception.
I use a skin in my app,and load something like 1.5 Mb of images at some of the activities.
This shouldn't be a problem.... 1.5 Mb + default of ~6Mb for the app when loaded... however, things are quite different.
each png I load as a drawable in my layout xmls, is being multiplied by at least 10 from its actual size...., I wrote a sample app with nothing except for a black screen, and loaded it once without anything on it and got native-heap of 5.8Mb, and then loaded it with a small png of 25Kb and guess what.... 6.25Mb.
I loaded my application with nothing but the skin, and it started with 14.5Mb!!!!!!!!
so now I am in the middle of doing a bitmap recycle operation after each and every activity change.
Is this a known issue with android?
png files are loaded with much bigger size inside the native-heap?
is there a solution other than my current plan?
Thanks.
PNG files (as well as many other image formats, such as JPEG) are compressed files, pretty much similar to zip-files. When you load them into memory they will be uncompressed
and take more space consequently.
How much depends on the internal image config, the default is ARGB8888, which takes 4 bytes per pixel. So the memory consumption only depends on the image size, not on the filesize on disk (which can get pretty small. For example: A 500x500 px bitmap consisting of one color has a good compression ratio).
Example for a 500x500 px image is 500*500*4 bytes = 0.954 MB, which is almost one megabyte.