In terms of RAM utilized by a drawable when it is rendered on on the screen, does it make any difference if the drawable is a vector or a bitmap?
I understand that vectors take less media storage space, but I'm asking about the resident RAM needed in order to render it, since in theory, it is still being drawn onto a canvas with the same amount of pixels in the end.
Thanks!
From the document I read sometime ago (same question with you).
The different between these 2 options is the size of APK file after all when you release. SVG will help you save size of apk.
The initial loading of a vector graphic can cost more CPU cycles than the corresponding raster image. Afterward, memory use and performance are similar between the two. We recommend that you limit a vector image to a maximum of 200 x 200 dp; otherwise, it can take too long to draw.
Being drawn on view will have those 2 options having same RAM (memory) consumed.
My reference source: https://developer.android.com/studio/write/vector-asset-studio.html#about
use vector drawables for simple shapes. Using the same for complex structures will increase the size of the apk rapidly.
Related
I would like to know what the pros and cons of using drawable vector shapes (XML files) vs image resources (png files) for icons (Material Design Icons)?
As I see, the question refers to general alternative between raster (e.g. jpeg, png) and vector (e.g. eps image). In one sentence, vector can be easily scaled and required less memory, but is more complicated. In details, see e.g. here.
The difference stands in vector images describing what they want to draw and raster images describing the color of each pixel, due to which these are heavier in size.
Vector images can be resized flawlessly, while attempting it on raster images is always a bad idea, which makes those images lose their quality.
Moreover, vector images are rendered slower than raster ones when there are many elements, due to the computations necessary to parse paths and shapes and draw them (indeed, vector images are more CPU intensive to render). Rather, it is faster if there are just few elements and paths have few points. Though vector images are lighter to load (in RAM; in fact they cannot be loaded in the GPU memory, unlike raster images), which makes them the fastest.
The important is, don't exceed with the number of elements in SVGs and other vector images. Otherwise, they'd end up being slower.
It depends on your needs to use which one. you can change vectors attributes with xml code anywhere you want. but image resources has less Flexibility to control its attrs and use more memory
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.
What are the pixel dimentions usualy used for games?
My game would be on Android and Desktop. I dont want pixelart images. I whant smooth images (like Fruit Ninja) at first for 2D games but 3D would nice to be known.
Should I daw my images in PoT?
Draw Images in low / mid / high resolution and the user define the quality?
What dimentions are usual for the low / mid / high res. images?
What res. would a big company like CD Project RED or Ubisoft use?
You should draw your images in whatever size makes sense for you. Also, you should pack multiple images into a single texture which should be power of two sized. Which size per image you use depends on your needs but it should typically not exceed the size (in pixels) of the target screen it is actually displayed on. You could use multiple files depending on resolution. But overall it sounds like you're trying to solve an non-existing problem.
I am fighting against OutOfMemoryError in my app.
I created a background image, which is 800 pixel x 480 pixel. When this image is loaded into the view that uses it as background, I think the OS will use 800*480*4 bytes for it. It is a lot of memory.
If I create a 10 pixel x 10 pixel 9-patch image to replace the whole screen image. The OS will auto-scale the 9-patch image to 800x480 when it renders the view that uses the 9-patch. My question is that, in the 9-patch case, how much memory will OS use to draw the scaled 9-patch image? will it be 10*10*4 bytes or 800*480*4 bytes?
Thanks.
Firstly, if it is a background image, and could be scaled, please do so, as it is known to be the best practice (especially for backgrounds) and the slight loss of image clarity could be compensated by choosing the correct colours and/or background pattern.
Regarding memory, if you are using Drawable you are on the safe side. But the Bitmaps are apparently not allocated in a standard Java way but via native calls; the allocations are done outside of the virtual heap, but are counted against it. More on this problem here
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.