The official documentation Vector Asset Studio states that SVG can be used to reduce APK size. It also states that SVGs take much CPU cycles for drawing.
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.
Also, it is supported from Lollipop onwards. On backward compatibility, it states that-
Android 4.4 (API level 20) and lower doesn't support vector drawables.
If your minimum API level is set at one of these API levels, you have
two options when using Vector Asset Studio: generate Portable Network
Graphic (PNG) files (the default) or use the Support Library.
For backward-compatibility, Vector Asset Studio generates raster
images of the vector drawable. The vector and raster drawables are
packaged together in the APK.
Raster images look like more efficient than the SVGs. Also, though the size of APK will be reduced, what will be the impact of SVG on memory and app performance as the doc states that it will take time to draw large SVG files.
As an android developer, what should be my approach? Which of above or any other ways will ensure my apps be optimized and deliver good performance.
Edit : A query then, What should be the best approach among the two -
Reduce the apk size by using the SVGs but will increase CPU cycles for drawing
Use raster images
In my own experience Vector Asset Studio is picky about what it accepts in an SVG. If you are not well versed in SVG you are going to have a hard time massaging the SVG markup into something that VAS accepts. From the top of my head I recall it doesn't support defs or filter, but some vector graphics software seems to include it even if it's not strictly necessary. Given flat icons (no gradients or shadows, for example) you can work around this by manually editing the mark-up.
As for performance, it really depends on the amount of icons you will display per screen, and the complexity of these icons. You will have to conduct some stress tests to see if your target devices hold up. Note that this only impacts the initial load, behind the scenes these vector images are rasterized and—as the text you cited mentions: Afterward, memory use and performance are similar between the two.
Your approach should be pragmatic, attempt to draw a couple of your icons on the screen and see how smoothly it goes. This is a subjective question that depends on the constraints of the device and the person who implements it.
My experience using react-native-svg was very good, but animation performance that needs to recompute dynamic SVG suffered from I think they call it 'too many passes over the bridge'. There may be a way to optimise it, and I intend to investigate this on my next RN project. I should qualify this last statement by emphasising that animation only suffers when the SVG needs to be recomputed during the animation (on the JS side). For example have a native ScrollView component with your SVGs inside it, the ScrollView can animate perfectly performantly, but if you want to change the SVGs programatically as a function of scroll position within the React/JS side, you will have the bridge problem, and dropped frames galore.
Here is my boilerplate which sets up a few basic shapes in Android RN:
proto__33__boilerplate
Generally I would say (programmatic) SVGs are great for Android, but I haven't yet found a performant way to use them for animations. Will update if I find that.
Related
I have a sophisticated design for an Android app and designed using Photoshop.
The app has many drawings and curves which mean I can't use Android Studio to develop it there.
I know there are many ways to slice in Android, but I can't find the best way yet to finish the job quicker and with a higher quality.
The VERY BEST solution - use Zepline online service: https://zeplin.io/ .
It is, this service authomatically calculates all dimensions in 'dp' (you don't have to calculate everything manually)- just select widget and see margins, space between elements, etc. But, the MOST useful thing, is that it converts your pictures into .png files to drawables for ALL densities. It releive you from pain of scanling up and down all pictures.
I have used lots of images in my android application and now my application size is too big. How can I reduce my android app size without deleting the images
Some advices that might be helpful:
Take advantage of xml drawables (reference), whenever possible.
Use SVG graphics, if possible. Vector graphics is usually smaller than bitmap graphics. And it will allow to use a single image for all resolutions, due to its intrinsic scalability. You will need a small 3rd party library, like androidsvg or similar ones.
Use 9 patches (tutorial) when you can, and you will save a lot of (normally wasted) pixels in your backgrounds.
Shrink your PNGs with a tool like OptiPNG or similar. They shrink your graphics preserving quality.
And more:
Remove any debug info.
Avoid duplicated code.
I am working with AndEngine and OpenGL ES 2.0. I keep reading about GL_MAX_TEXTURE_SIZE and how I should keep my texures under 1024x1024. I started wrong before and while using tilesets in TMX extension (doesn't really matter what it is, if you don't know AndEngine) I get to a tileset that makes a texture wider than 1024px. I am thinking of splitting the tileset into two, making them "safe". But I can't find any device released in last couple of years that has this limit set under 2048x2048. Is there any list or website I can use to filter devices by GL_MAX_TEXTURE_SIZE?
I read the following questions:
Minimum required Texture Size for compliance with OpenGL-ES 2.0 on Android?
Is there any Android device with screen size greater than GL_MAX_TEXTURE_SIZE?
And I used this site to search for devices. But I can't search by/filter by GL_MAX_TEXTURE_SIZE, which makes the search tedious. I am asking mostly because I started wrong, it's a hobby project and the amount of work might be too large compared to the number of possible devices that will be enabled (I expect 0).
1024x1024 is about the safest you can go on any device, especially on older ones. Newer devices shouldn't have any problem, although I've seen recent devices (I recall a Galaxy Nexus, the newest ICS update fixed that though) render white quads with texture sizes of size 2048x1024.
If you're targeting new devices and want to keep older ones compatible, it shouldn't hurt to split your tilesets. After all, you aren't likely to do too many context switches if you use two or three spritesheets for background, etc.
If you still have the individual image files, breaking them into small sized Atlases or custom sized atlases is easy if you use the TexturePacker2 tool from the LibGdx library.
I don't know the exact limitation of devices, but it's always better to take into consideration the lowest end of device you want to support and build upward from there. Using the LibGdx tool, you can easily change your mind later, so it's the most flexible solution.
Look at:
LibGdx TexturePacker
I'm quite a noob with libGDX for Android (nice OpenGL wrapper that can also work on PC), and I've read some nice examples of how to show images and shapes.
However, when I wanted to check out how to show text, I noticed that the only thing I could see that this library supports is BitmapFont, which uses a bitmap for each character. It's ok for some resolutions and font sizes, but it becomes blurry/pixelated for other cases.
Is there any other way to show text using this cool library? Some kind of way to show vector fonts, and also use more popular fonts files extensions other than ".fnt"?
There is a recent entry on the badlogic blog about generating bitmap fonts on the fly from TrueType font files that should address your problems with packaged font files that are ugly when scaled.
When I was new to Android and libGDX I spent some time looking for a vector font solution to draw scalable text via libGDX. I never found anything (not even generic Java or generic Android). Most font solutions I found are built on bitmaps or were very complex rendering systems (that would be hard to adapt to OpenGL). This seems a bit odd to me too, and I haven't found a coherent explanation.
I don't think there is a proper ways to do so, because libgdx works on openGL too. OpenGL uses textures for displaying images, so that your device is able to draw images hardware accelerated. I don't use libgdx but probably you can write your own function to draw first your vector-based fonts on a texture and then draw your texture on screen. -> But then it's not vectorized anymore.
I am trying to address a resolution issue when designing HTML for webkit browsers.
So basically the problem is that webkit browsers can have resolution anywhere from 240x320 to 960x640 and I can't have a separate image/icon set for each one but I do want the pages to look the same on all devices (or very close at least).
Scaling the image (working with percentages) works but it's a performance degrade:
http://code.google.com/speed/page-speed/docs/rendering.html#SpecifyImageDimensions
The other option is using vector graphics which is supported in webkit but I am not aware of the performance implications that is going to have on the pages/app.
The other option is to have a few icon sets for some standard well know resolutions and when you get a browser which is outside of these groups you apply some minor scaling on the set which is closest to the users native resolution.
So basically what I am asking is, what would be the best route to achieve this with performance in mind?
Thanks
-Assaf
Vector graphics are always more expensive in terms of runtime performance as complex equations are run to create them. Having said that, I'm not sure if they're redrawn every frame from scratch, or if the result's cached unless it's in a dirty state.
I'd suggest having a few different icon sets for well known resolutions and applying minor scaling if required.
The first answer is not helpful at all. Vector graphics can be just as small as a PNG, and used right can support transparency and various other good features.
The only problem is if your looking for pixel perfect perfection having some of the images scale up might cause problems.
You can also use illustrator to html5 canvas plugin to export directly to html5 canvas.
For our webkit browsers on row icons, we set a property that doesn't allow webkit to scale the icons for desktop browsers. Or for some of the icons we include a small SVG.
They are well supported and work great. Even better would be to use a free font creation tool and paste your vector graphics from illustrator into a font, so that you could use web-font to simply call up ANY size icon, as simple text. We use this technic.