I do not really understand all those things about pixel density and device independant pixels and I want to know if I should worry about this.
More specifically, here is how my application work right now:
For the “layout screens”, I’m using RelativeLayout or LinearLayout and I never use pixels or dp, so I guess that this will look good on every device
For the main game screen, there is only a SurfaceView on the screen. With the values given by onSurfaceCreated() (pixels or dp? I don’t know), I compute the size and position of every element of the game, then I load the Bitmaps (with BitmapFactory.decodeResource() and then Bitmap.createScaledBitmap()) and put them on the screen with drawBitmap()
I tested on my phone (480 × 800 hdpi) and on the emulator (240 × 320 mdpi), and both looks good.
My questions are:
Is this the right thing to do? I do not understand how (and why) I could use the fact that some devices are hdpi and others are mdpi.
Should I provide different bitmaps for different screen densities, and why? (right now I have everything in res/drawable-hdpi)
What size should my .png have? Can I create them much bigger (2 ×) than their expected size, in order to be sure that this will not look blur or aliased?
My knowledge about this is limited, as i never developed games.. as i supposed you are doing.
Is this the right thing to do? I do
not understand how (and why) I could
use the fact that some devices are
hdpi and others are mdpi.
With this information you can load different images automatically. You can you the directories:
drawable-hdpi
drawables-mdpi
...
Should I provide different bitmaps for
different screen densities, and why?
(right now I have everything in
res/drawable-hdpi)
If you have all in hdpi then the images will be shrinked i think, to be smaller due to the lack of specific images o that scale. Providing the images will give you more control over the final product and it will spend less processing.
What size should my .png have? Can I
create them much bigger (2 ×) than
their expected size, in order to be
sure that this will not look blur or
aliased?
I think they can be exactly the size needed. But as i said above.. not much experience.
Related
I'm trying to specify the art sizes for an Android game with ~10 screens. I want the game to run on API 8+, and on all size screens except "small".
Since we're using API 8, I use the old "4 categories of screen" feature - I plan to support
normal (480 x 320, and up to 640 x 480)
large (640 x 480, and up to 960 x 720)
xlarge (960 x 720, and up to 1920 x 1200)
A 1920x1200 png file is ~4.1MB. So 10 of them is 41MB, and we've almost blown our 50 MB app size limit (Play Store).
So three questions:
1. how do people support detailed artwork for game screens? Do I have to use bland colored 9 patch pngs files for the backgrounds? Or is it feasible to store all art at the 960x720 size, and allow it to be resized by Android for large and normal screens? 10 background files of this size total to about 15 MB, which leaves 35 MB for everything else.
What if I used jpgs instead of pngs? How much quality would I lose? Since I would only ever be downsizing, this should be OK, right? 10 jpgs of 960x720 is only 4.3MB.
If I allow Android to resize it, how do I support screens that have a different aspect ratio than the 4:3 of 960x720? Is there a way to specify in the layout XML "use the drawables from the large folder, but "letter box" it onto the screen, so that the longest dimension just fits" ? (And for xlarge screens bigger than 960x720, just put the drawable in the middle of the screen - don't stretch it at all)?
DPI resolution of the screen doesn't factor in this at all? DPI only needs to be taken into account when you want something to be roughly the same size on different res screens, like an icon or button. Correct?
Seems like this should be a solved problem with a well known pattern or template to follow. How have other people done it? Does everyone use either huge downloads post install (want to avoid) or 9 patch backgrounds?
Thanks in advance for any advice. I searched here on several terms, and looked at about 25 past answers, without finding what I am looking for.
Peter
Resurrecting the dead (thread): one way of doing things could be to provide just one set of bitmaps and do the scaling yourself. You can either provide large bitmaps and scale them down, or provide middle of the road bitmaps and scale them up (for large screens) and down (for smaller sizes).
The benefits of the former are that your art looks great on large screens and you are a bit more future proof (if you provide for this in your code). The downside is that you could (and actually likely will) run into Out Of Memory/Exceeding VM errors when decoding/loading these bitmaps on lower-end devices, even when doing it carefully. So I usually go for the second approach.
Scaling up can be done a number of ways, but one is to just load in the bmp at it's default size (use getResources().openRawResource(id) or BitmapFactory.decodeResource(etc) or even better use inputstreams or [according to some the best method] load/create using the FileDescriptor methods) and then scale it either by creating another bmp using createScaledBitmap() or if drawing to a canvas draw it to a destination Rectangle (better memory wise).
For scaling down you can either use BitmapOptions like .inScaled or, again, use a smaller destination Rect in your canvas drawcall.
Doing it this way is way better and (for a game) faster than letting Android scale for you using those buckets (hdpi etc) and uses less memory if done right.
But beware as some bitmap loading methods are a bit buggy and create 'the bmp is too big for the VM' errors. Also learn to dispose of your bmps properly; a lot of people and Google/Googlers say Android does this and you don't have to set your bmps to null and recycle() them, but so far I've found that you do. Another caveat is to set the proper options (filtering/antialiasing etc) to prevent blurry bmps. And take care of un-optimal color/format/dpi settings on BitmapOptions/canvasses/SurfaceViews and even windows.
There's much more, but this should help anyone get started.
Sorry but i cant understand how i can draw a right picture for the right android phone size.
I readed the android documentation, and they say for i just think in screen size and density and not in resolution, so what size should have my picture?
For example,if i have a phone with size 1000x400(stupid example),and want a button(40x40) that will be in middle,what size should i do?? 40x40?? But in documention they say for dont look for resolution :\
Im confuse...
ps: The documention link Android multiple screens
Basically you'll have to realize that although resolution, screen size and screen density are separate attributes, they are still somewhat related. If your button is 40x40 as you mentioned, and that's the size you find looks good in the center on a hdpi(high density) device, you will have to scale it so that it fits accordingly on mdpi(medium density) and xhdpi(extra high density) devices. What I like to do is use PhotoShop or another graphical editor and resize my assets so that they fit on whatever density devices I'm trying to target. I make sure to always use *WRAP_CONTENT* for my height and width attributes and never fixed values.
Also, if you do not include these scaled alternatives in your res/drawable folders..you're basically saying that you're relying on the system to scale them for you, which can be a gamble. So I always go with resizing my assets so that I include a version for all densities. The link you posed explains everything pretty well
Simple question actually and I have spent hours searching for an answer.
What is the best way to provide bitmap resources that fill the full screen? For instance for a full app background or something.
Currently I place all my images in drawable-nodpi in a medium resolution and obviously need a lot of custom scaling. I do need images the fill the full, or the half or a third of the screen width. What is the best way?
Michael Ellen states ( https://stackoverflow.com/a/6938345/1162415 ) that e.g. drawable-ldpi has 240 px screen width. While I would love this to be true I do not think so. Table 3 at http://developer.android.com/guide/practices/screens_support.html#testing clearly says that ldpi might result in actual px resoluation width of 240, 480 or 600.
Should I build the app with drawable-*dpi fixed for screen sizes, something like drawable-ldpi-small and so on? We do make use of 78 cards ( https://play.google.com/store/apps/details?id=com.pinkwerther.tarot if you are interested) which should be displayed almost full screen. That makes a hell of an overall app size. Either that or a hell of a lot of different apk files.
Now there is one solution I am currently thinking of that might be suitable. Namely to provide kind of low resolution default images and have the apk with an expansion file ( http://developer.android.com/guide/google/play/expansion-files.html ) of really high resolution images which get scaled and stored on first use. Before I dive into this possibility I just want to make sure there is no simpler solution... So please feel free to hint me to the hidden places I happen not to be aware of!
I'm writing a game for Android and can now test it on a second device, the Nexus 1. The game uses fix pixel-values, just using bigger cutouts of the background for high-res devices. So I thought there would be no problems. Somehow, however, the nexus 1 is making a specific image bigger than it should be (261*66 instead of 174*44). The picture itself as a resource is 174*44, so it's being stretched. Why? What can I do against it?
Edit:
Spritesheet = BitmapFactory.decodeResource(res,
R.drawable.bird_spritesheet);
Is the used code.
Edit 2:
Is there no way to tell the software to just use the size the picture is? I don't want to bloat my software by adding multiple pictures (/drawable-hdpi/ answer).
The pictures are supposed to be smaller on bigger screens.
what drawables folder to you have the picture in? If you put a copy of it in drawables-hdpi I think it will show up real size. It is really better to set things up in such as way that the final size in pixels it ends up is unimportant. Using pixels values is going to ensure that your app looks wrong on at least some of the screen sizes out there.
Because Android runs on multiple screen sizes and you use device independent pixels (DIPs), images get scaled to ensure they look the same on all devices. To avoid this, you can provide alternative resources for high density screens (in your case) and for low density screens.
More info about screens here
I'm wanting to target WVGA (480x800) and FWVGA (480x854) devices with my program. My question is: for my full screen background bitmaps which resolution should I make them?
There are a few ways you can attack this issue.
Make one background per aspect ratio and calculate which to use when the app starts. Find the aspect ratio by dividing the width by the height.
Make one background with filler on the sides and bottom for cropping, when you display the image resize it's dimension which has the largest difference from that of the screen's resolution to the exact screen resolution. This will cause the bottom or sides to get cropped a bit.
You could also use a combination of these strategies to create a couple backgrounds, one each for a range of aspect ratios, and then use the cropping strategy to take up the negligible difference.
Be flexible. Android can be run on many different devices, and it would be a very bad idea to limit yourself to certain resolutions. Instead, write your code so that it scales. (Keep it mind that you might have to crop the image if necessary, or live with different aspect ratios).
Just as food for thought... there are Android devices with 480x320, 240x320, 480x800, 480x854, not the mention the upcoming Samsung tablet at a higher resolution. Limiting yourself to a certain resolution would be bad.
Here is something from the SDK you may want to read up on too: http://developer.android.com/guide/practices/screens_support.html
EDIT: Assuming that you're focusing on those two resolutions -- I would say it depends on your image. Your best bet may be to go for 480x854 and design the image in such a way that it won't look bad if you lose 27 bytes on either side. If that's impossible, make it 480x800 and add black bars on either side if run on 480x854.
you can get any bitmap and convert it into a drawable using BitmapDrawable .Then you can set bounds to the drawable to match your screen background.
I've made my background graphics 480x864, the hdpi equivalent of WQVGA and thus as large as it gets. Since I center background graphics vertically, this will display nicely on QVGA, HVGA, WQVGA and WVGA, cropping a bit in most cases. To make sure that the important elements are always seen, I limit them to an area of 480x640 in the center.
To leave nothing to chance, I provide scaled down versions of the graphics at the same aspect ratio for MDPI and LDPI. Works great so far.