Android: Is 2D drawing faster than setting images in ImageViews? - android

I am creating a dress up game, and this involves putting lots of images on top of each other. The application by itself can work fast with no lags, but if a slide animation is added to the item to be dressed when the character is fully dressed (10 images or more on top of each other), a bad lag happens. I believe this happens because the OS invalidates all the ImageViews and draws them all again. The images are of png type and they mostly are around 10 kilobytes.
Would using graphics and drawing on the layout make it faster? Or would it be the same thing as setting images from resources?
I can't actually try it right now because it involves a major re-writing of the code.

If you implement the app using OpenGL, it should be more faster than now. Before doing that, you might want to double check that you have all the image resources scaled correctly for the target devices (mdpi, hdpi, xhdpi, and xxhdpi). Scaling up drawables in runtime can cause a significant performance penalty on some devices, especially for animations.

Related

How to can I create an image that can be used for different android screen sizes?

I created an image to use for an android splash screen and it displays properly on my phone however when I open the app on a phone with a larger screen it pixelates. So I was wonder if I should create more than one image and if so what sizes should I set for other images because I know I can't use the same sizes as I used for the app icon?
If the images are pixelated
then you need to add larger images for each screen size under your
res folder. sizes depends on your target
or
scale the images. to be safe, make it bigger
it might help you: am I supposed to make images larger for tablets, or same size as handset?
you could probably use draw-9-patch to state which area of the picture can be extended.
Google draw-9-patch
I worked with two approaches so far:
Screen composition
One approach can be using a composition of brackground and a logo. You can have the logo as big as you need (for high resolution screens) and the background as a repeatable texture (it all depends on your design approach) or a gradient or other composition (less prone to pixelation errors).
As big as possible approach
If one image is your approach, you should do a research to know the currently most used and biggest android screen used (https://developer.android.com/about/dashboards/index.html). Knowing that one, you can design your image for that [high] resolution and set the scaleType as CENTER_CROP. With that, you will ensure that the image will be centered, inside the screen, keeping aspect ratio, and at its highest resolution [keep an eye about logos/graphics positions if you want to be sure that they remain visible even in thin screens).
For icons, the best way is Draw 9-patch
Otherwise, you need to scale the images into drawable-xx (res directory), here the explanation

How to render editable layers

I writing a image compositing app where it should be possible to arrange images on different layers. So what I currently do is to merge (draw one bitmap after another) on a canvas.
The user should be able to remove any of the layers at any time (also undo).
My problem is related to memory management: I fear OutOfMemoryExceptions when keeping every layer as bitmap object in memory. But merging is a problem: As soon as I merge all bitmaps, there is no way to separate them again (obviously).
I was wondering about saveLayer, it seems you can save and restore data, but I don't really understand whether it could be helpful for me.
I thought about reducing the resolution of the images on the layers, but then the question "which resolution is the right one?" pops up. After all the resolution would depend on the (dynamic) amount of layers and the available system memory.
Anyone has a proposal on how to handle this requirement?
For the merging problem, what if you instead had multiple canvases, perhaps as part of a custom ImageView, which you dynamically add as layers in a FrameLayout? The compositing part would then be simply handled by the layout, and you could your make your draggable images appear/disappear without redrawing the unaffected images simply by adding/removing views from FrameLayout.
For the memory issue, I can't think of many ideas except to a) set the max res of each layer to something sensible given the devices screen size, b) experiment with using compressed bitmaps like Bitmap.Config.RGB_565 (with a perhaps unacceptable compromise in color fidelity), c) query the usable heap size and limit the number of layers accordingly.

Android: Purpose of using images with different pixel density?

I know using images with different DPI is a fairly common practice in Android. But I don't really see the purpose of it, why can't we just use a ultra huge image and then scale it in the program? I know we probably need to do extra calculation if we don't images in different DPI, but besides that, is there's any other reason?
Tim and a.d. have the correct reasoning for you. Here's a visual example if you'd like to see a comparison between something rescaled or drawn at the correct size. Effects are always more noticeable if there are very small details.
The first is a large 200x200 (we'll call it xhdpi), and the second is simply the same image resampled for mdpi (75x75). The third is redesigned to the same specs but starting at 75x75. As you can see, the text on the second is significantly blurred, and there are some artifacts along the edges of the shapes where rescaled.
you get optimized images for the density of the screen. if you leave it all for xhdpi , you must know that some important pixels might be gone in the process , because you didn't pay attention to that .
if you don't care about speed and accuracy , and you think that people won't notice important pixels being missing , it's ok to use this approach .
not only that , but if you scale the images yourself (using weights, for example) , you don't need to put them in dpi folders at all - you can put them in drawable-nodpi folder.
By providing images that are already rendered to appropriate sizes for each of the major classes of screen density you avoid the need to explicitly do the scaling within your code, which will make for "cleaner" code.
You also avoid the performance drain that would result from each and every image being shown having to be scaled, depending on exactly how much scaling your app would have to do it could be a significant boost to performance to not do these operations "on the fly" as the Views are being shown to users.
And lastly providing appropriately rendered images for each size will ensure that your resources look nicer. The system scaling is not perfect and will errode the "clearness" of your images if it has to scale them at all. If it has to scale them significantly this will be noticeable to the user.

Efficient loading of pictures using OpenGL

I am developing a 2D game for android using lots of sprites. I am drawing on the screen using OpenGL ES. I separeted the sprites into several pictures (around 7). I read, that loading a picture into memory takes most of the time. Every picture contains a diffrent category of images: for example - background elements, enemy units, etc, etc. I load them in a defined order: background picture first, so background elements are drawn at the bottom, then the enemy units, etc. But what should I do, if I want to draw elements of the background at the top of the canvas. Should I load the picture with background elements twice? Or store that special element in both pictures - the background picture and the picture containg top elements. Or there is a better way? Thanks!
Loading has nothing to do with rendering. As long as you render something after you've loaded it, then you're fine. The order that things get rendered in is not affected by the order you loaded them in.
Now, if it's an issue of memory (ie: you can't load everything at once), then the steps you need to take depend greatly on exactly what you're doing. We can't really give you anything more than general advice, because we don't know everything about what you're doing.
In general, you need to break down your rendered world into chunks that fit in memory. This will put constraints on your design: you can't use stuff (be it backgrounds, enemy units, whatever) from outside of that chunk. Since you're developing on limited platforms, you're just going to have to put up with those constraints.

Using image sprites on android

I have an image (588x449) sprite with a collection of different team logos. In Android I have the corresponding ImageView displaying this:
<ImageView android:id="#+id/image_team_logo"
android:src="#drawable/teamheaderssprite"
android:layout_height="25dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:layout_width="296dp" android:scaleType="matrix"/>
The above will correctly display the piece of my image in the upper left hand corner. My issue is I want to be able to move the position in the image being displayed so I can jump to another area in the sprite. This is pretty common practice in html/css, I am just not seeing a 'position' type property in android xml.
You can't use sprites in the same way on Android you can with HTML. There is one way I can think of to simulate sprites though: Lay the sprite out entirely horizontally (or vertically), then use a ClipDrawable to define each level as a new part of the sprite. Then define the level of each View as appropriate. (If the images in the sprite aren't all the same size, you may need to use InsetDrawable as well.)
However, I would seriously rethink using sprites in Android. There are reasons why web pages use sprites, and it's not because they're easier - it's because it speeds up webpages because you don't have to make multiple HTTP requests. Since the images will already be in your release APK, you don't gain anything by spriting them.
Not only that, but you're doing some harm by spriting on Android:
Memory constraints on some Android phones are much lower than you might expect. If the entirety of your graphics are in memory at any given time, that lowers the amount of memory you have for everything else.
Sprites will be harder to handle once you start writing for different screen densities (ldpi, mdpi, hdpi).

Categories

Resources