Android: Purpose of using images with different pixel density? - android

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.

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

Android: Doing all my drawing on a SurfaceView; what's the proper way of making sure my drawing conforms to any screen size?

I'm making an app (a game, to be exact) where each activity uses a SurfaceView for the UI. All of the drawing is done through onDraw. I am also designing this to use no Bitmap assets, so everything that is drawn is produced directly by the app. I'm trying to design the app in such a way that it can easily be viewed on any screen size.
So here's how I'm accomplishing this: I'm doing my testing on a Galaxy S4, which has a screen size of 1080x1920. In the constructor for each activity, the width and height of the current screen are calculated and stored as ints "w" and "h" (the app is already locked in portrait). Then, whenever anything needs to be drawn onto the screen, I multiply the desired dimension (as seen on my 1080x1920 screen) by either w or h, and then divide by 1080 or 1920. Since I'm not using any Bitmap assets, I never need to worry about pixelated images or anything this way.
This gets the job done, but seems like a bit of a roundabout way of doing it. I figured there would be a better framework for getting this done, and I'm worried that these big calculations are eating into my drawing time (running at 30FPS can get a little jerky).
Is this is the customary way of doing it, or is there a better way out there?
There's a very simple yet effective way to do it, you can declare all your sizes in a dimen file for each specific density/size, as you usually do for layouts e.g:
values/dimens.xml <--- With default sizes
values-sw600dp/dimens.xml <-- Tablets sizes
(etc...)
Now before you start drawing, load all the values in your program only once, maybe onCreate of your drawing activity, using the following command:
float someItemSize = Context.getResources().getDimension(R.dimen.some_itemSize)
etc...
That way, you let the operating system do the pixels conversion for you, you should do it only once and most important, this will give alot of flexibility to your code because you will be able to change sizes from xml files without even touching your actual code, hence, the customization should be easier as well as future changes...
Hope it helps!
Regards!
There are two considerations: screen size and screen aspect ratio. If you simply scale everything to match the display, you will appear stretched a bit if you put a 4:3 device next to a 16:9 device.
You generally have two options for dealing with the aspect ratio: you can letterbox / pillarbox the output (which is fine for movies, but looks kinda lame for an app), or you can recognize that your output isn't always proportionately the same, and adjust the layout to fit nicely on the screen.
As far as size matching goes, when using a SurfaceView you can actually use a single size and then let the hardware scaler handle the rest. For an example of this, see the "Hardware scaler exerciser" in Grafika. I put a demo video here, though it's a bit hard to evaluate after getting rinsed through screenrecord + youtube. What you're seeing is the same couple of shapes rendered onto a Surface whose size has been set to an arbitrary value, and then scaled up to match the display. This is most obvious on the final setting, where it's drawing on a 106x64 surface.
With this, you could size your assets for 720p and always draw them the same way, and let the scaler deal with the stretching. See also this blog post.

What is the purpose of 9-patch for android? Can I use it for buttons which are in circular shape?

I have an button like this. I was asked to use 9-patch for android development. I am wondering how 9-patch is useful in this case. I am under impression that 9-patch scaling is for rectangular or squared which are in rounded corners so that even content inside grows the container stretches without the distortion. Please help me understand the actual purpose of the 9-patch scaling for Android. Thanks.
The content is scalable, the edges will not be scaled, in typical usage.
They're generally used for backgrounds to buttons, or other screen decorations, where the scaled content can be scaled infinitely without losing resolution.
Ideally, they're used in addition to density-dependent resources where appropriate, so that the section of the resource (which you didn't explicitly state is scalable) isn't upscaled and subsequently pixelated.
Consider the splash screen for the Kindle app on Android, which features a silhouette of that boy reading against a tree. In a simplified version, the ground can be scaled horizontally infinitely, but if the boy was scaled, he'd appear skewed. So you could use a nine-patch and specify the section which can be scaled, and in which direction.
That's not enough though - if you only included a low resolution resource, the resource would still be scaled up initially if the device display was of a higher density. In this instance, the boy might look blurred from the upscaling, and is an example of when a higher resolution resource could have helped prevent the pixelation.
The way you've phrased the question suggests (to me) that you're asking whether 9-patch images can replace all drawable resources, like icons or resources with pictures in them, to which the answer is no. They're only to be used to scale sections of resources which feature a block of a single colour (i.e. sections which cannot be pixelated).
--
http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch
Please help me understand the actual purpose of the 9-patch scaling
for Android
There are many situations where you find yourself needing the same button style but in different sizes.
So in that case you will have to provide different size resources. But to avoid this, you can simplly provide a 9-patch image, which will be used irrespective of sizes.
Advantages of using 9-patch:
When used as background,image won't stretch and loose proportions in different screen sizes.
Saves memory.
9-patche images are small, reusable and scale nicely.
If you don' use 9-patch images, you will need to test on various sized screens.
9-Patch
A guide to 9-patch

Android non-repeating textured background

I have an iOS app that uses unique textured backgrounds (think of a game title screen or something) on each of the screens that I am trying to port to Android. On iOS they knew the resolutions and just designed the backgrounds around those. Obviously that isn't possible on Android.
What is the best way to put a textured/non-repeatable background into Android that works on various screen sizes and aspect ratios?
The solutions I have thought of so far are:
Fit the shortest dimension and allow the image to go off the edge of the screen for the larger dimension
Make the background image large and center it, then make it stretch out beyond the edges when the resolution is smaller than the image
Stretch the image to just fit (this is ugly and I'd like to avoid it)
Create a different version of the image for each resolution. (This seems way beyond the scope of what is possible for this project.)
As far as I can tell in Android, 1. and 2. aren't possible out of the box because background images set the size of the view to match their size (you can't tell it to just extend beyond the edges, please correct me if I am wrong).
What solutions would you use in this situation?
Use an (match_parent) ImageView to simulate back ground image. (By adjusting the scale type of imageview you can get the result of point 1,2)
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
Use 9-patch image. You can specify which part of your image can be stretched. For your case I suggest adding a small "margin" to your image, and make it stretchable using 9-patch. Only the margin will be stretched, maintaining the aspect ratio of your image.
android developer 9-patch
Create a different version of the image for each resolution.
As you're probably aware, Android can run on a wide variety of devices with varying resolutions and screen densities. To be fully compatible with all of them takes a bit of graphics work; you need resources for each possible screen density (and in this case, resolution).
For full details, see Supporting Multiple Screens in the Android developer documentation.
Unless something has gone seriously wrong in your development process, you should have the original files (e.g. .psd) to work with when creating these resources.

Android and supporting multiple screens layouts

I'm finishing off an Android app, all that remains is to adapt the UI layouts and graphics for multiple devices. I need particular elements placed in particular positions on the screen.
The Android docs explain how the multiple screen resolutions and sizes are classified, and explain the resource tagging system.
For example, both WVGA800 (480x800) and WVGA854 (480x854) are classified as normal high density screens. To cater for these you're asked to create a folder called "layout" (already present for "normal") and "drawable-hdpi".
The problem is this does nothing to differentiate two devices of the same classification, even if you use "dp" units. How can you provide layouts/drawables for WGA800 and for WGA854 separately?
The ratios are sufficiently different that the user easily notices bad scaling, and this is exacerbated by my need for things like a score and timer to appear in a particular place against a background image.
The same problem applies to the pairs {WQVGA400 (240x400), WQVGA432 (240x432)} and {WVGA800 (480x800), WVGA854 (480x854)}. How can you provide layout/drawables for WQVA400 and for WQGA432?
I think you're on the road to hell.
Android runs on an enormous variety of devices, more every week, and many formats don't exist yet but will introduce new variables. So even if you succeed, one new device with a slightly different screen size, and your app will fail.
It's a mistake to design for Android using specific screen resolutions, and is similar to the issues you'd find if you forced all pages to be the exact same size on the web, it rarely works well (e.g. even a tidy fixed-width site will fail miserably on mobile devices).
Android has been designed to support all this variation, but if you try to get pixel-perfect absolute-positioned rendering on every screen size you are swimming against the tide. It is likely to be very painful, very time consuming and expensive, and likely to ultimately fail. Even if you succeed, how on earth will you test it on all these screen variants? It sounds like testing hell too.
I STRONGLY recommend you accept you cannot do everything as exactly as you need to, and instead look at how to use ways of rendering objects fluidly, relative to each other, so the app looks good in all the different variations, using the different layouts for each group of resolutions to improve the experience on different size screens.
YES, that's possible:
First you have to create a instance of the display-class.
After that you get the display's width and heigth.
Then you can check each resolution in a loop, by using the if operator and set the image you want.
Example:
ImageView iview=(ImageView)findViewById(R.id.imageView1);
//here are the Bitmaps optimized for each screen resolution
Bitmap[] bitmaps={BitmapFactory.decodeResource(getResources(), R.drawable.icwvga800),BitmapFactory.decodeResource(getResources(), R.drawable.icwvga854),(...)};
// In this list all supported screensizes are defined
int[][] possibleScreenSolutions={{480,800},{480,854},{240,400},{240,432},{480,800},{480,854}};
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int[] ScreenSolution={display.getWidth(),display.getHeight()};
// Compare the real screen solution with the all supported ones
for(int i=0;i<possibleScreenSolutions.length;i++){
if((ScreenSolution[0]==possibleScreenSolutions[i][0])&&(ScreenSolution[1]==possibleScreenSolutions[i][1])){
iview.setImageBitmap(bitmaps[i]);// set the image
}
}
I agree with Ollie C: It's too confusing to check all resolutions, but It's at least possible.
I've tested it allready: It works.
Further to the answer/comments elsewhere on this page, I'd like to post another answer to my own question drawing attention to the type of screen resources that can be introduced. I'm not convinced this is made clear in the Android docs, but so far as drawables are concerned you can add screen size tags to drawable files on top of the dpi tag.
For example, adding a folder called drawable-large-mdpi is valid and devices with large screens and medium resolution will pull resources from here if they can. Warning though, switching the order of the tags matters: declaring drawable-mdpi-large is an error.

Categories

Resources