If I put my application resources in drawable-xdpi then it is automatically down converted for hdpi, mdpi and ldpi by ration 0.75, 0.05 and so on.
Why we need to create extra resource if one type is enough only?
I believe it is enough if I create for xhdpi and let Android down scales automatically. I have gone through this question
What is the best way to create drawables for different dpi
but no one has given answer that yes you can go this way.
Suppose I kept my images in xhdpi and when app opens in hdpi it will reduce size to 0.75, when it opens in mdpi it reduces size to 0.5.
So what is best way to create draw able asset? Please suggest perfect way with valid reason.
If not needed why we are creating so many resources instead for one only like xdpi?
There are two reasons to provide more than one image:
it is more efficient to load an image that is already the correct size.
The automatic downscaling may produce artifacts, which can be disturbing especially for small images. So if you want a pixel perfect image it is better to provide one in the correct size.
If none of them is a problem for you, it is also fine to go just with one image.
If u want to display same image with different resolutions in devices
xhdpi image then place it drawable-xhdpi
hdpi image then place it in drawable-hdpi**
or to maintain a drawable folder place all the images what you want to display it will display with same size in all devices irrespective of the resolution.
Related
I know that the title makes it sound like it is a duplicate, but I think I have a very specific situation here that I can't solve from all of my searches.
First, I have images that are specifically sized based off of a specific monitor (Yes, monitor. Not handheld device's screen). The images are based off of these specific settings:
1600x900 20" monitor at 96ppi
Now, all of the images must be sized in millimeters (they are square images btw, so Height=Width). Using these specific settings as a determining factor, 1mm = 3.78px. So, my images are sized using this. For example, for an image to appear as 65mm, I size the images to 246px. I tested this in Photoshop using these settings, and measuring the image on the screen did in fact come out correct.
So now in my Android application, I load up these images into ImageViews to be displayed. This is where I am stuck. The device is an MDPI device. If I load the images into the MDPI drawables folder, the images appear too large on the monitor. Using my above example, I convert the Drawable to a Bitmap and dump the Height of the image to my log. This is correct and shows 246px, but for some reason it is measuring well over 85mm instead of 65mm.
If I load all of my images into the HDPI (yes, I know it is an mdpi device so it will be sized by the Android OS), the height of the image (using my example) dumps as 164px and appears at roughly 50mm. This is more explainable, but still I am still confused on how to get these images to appear as they did in Photoshop.
So my question is, what is the best way to programmatically size the ImageView to be the exact size of the image? For my example, I need to find out why my 246px square image (at 96ppi) is not showing up as 65mm like it should.
Because these ImageViews are generated programmatically, I have tried the following two things:
Set the ImageView Height and Width (using LayoutParams) to the height of the image (246px). I did this thinking WRAP_CONTENT was not acting as it should.
Used ImageView.ScaleType.CENTER to try and make sure the ImageView is sized exactly to the image.
Neither of these things seem to have effected the output.
UPDATES:
I have verified that my device is a MDPI device. This means that there is not DPI to PX conversion (or vice versa) necessary because of the 1:1 relationship. Somewhere, the sizes are being increased and I cannot determine where. As I indicated in the comments for the answer below, when I pull my Drawable and convert it to Bitmap, it pulls the EXACT pixel Height that I made it. I am starting to figure out the percentage of size difference from what it should be (65mm vs 85mm) and it works out to be 23.529%. I am scaling my bitmaps subtracting this value, but it ruins the quality of my image.
I am beginning to give up.
The device I am utilizing is an MK802III Rockchip Device (Amazon Link)
Android modifies all images for display with the following formula:
px = dp * (dpi / 160)
Where "dpi" is the screen density in dots-per-inch of a device's display.
Additionally, Android looks through a hierarchy of drawable folders when deciding which image to display. As we all know, an HDPI device will use an image from the drawale-hdpi folder while an MDPI device will display the same named image from the drawable-mdpi directory.
However, when an MDPI device cannot find an image in the drawable-mdpi directory, it will eventually choose from the drawable-hdpi folder, but it will down-scale the image for display on the MDPI screen.
This explains why your image appears smaller when you saved it in the drawable-hdpi folder.
But, it does not explain why the image appears too large when correctly placed in the drawable-mdpi folder.
It so happens that:
65mm ~= 85mm * (120 / 160)
50mm ~= 85mm * (120 / 240)
This is the scaling that I would expect for your images if your device were LDPI (120dpi) instead of MDPI (160dpi) as reported.
I hate answering my own question, but I am just going to update everyone what I did. If someone comes up with a better solution, I am all ears. I had to force this along because I am on a tight deadline.
I created a dummy application that dumped boxes that I could measure. Using these, I determined that 1 millimeter is 3 density pixels. Let me repeat that, 1mm = 3dp.
Using this value, I resized all of my images (utilizing a PHP script) to this constraint. All of my images are appearing as normal. 195dp = 65mm, and it appears as such.
Like I said, any explanation as to why I had to do this and you get an upvote and answer.
I am kind of confused about managing graphic resources in Android.
Tried to read this doc but It only confuses me more. Can anyone give me some example of how should I handle the following case?
Lets assume that I have an image in my layout that will be scaled to fill screen width. What image sizes (in pixels) should I produce and what configuration qualifiers (drawable-{qualifier}) should I apply to those resources to cover all major dpi and screen sizes (both for tablet and handset)?
Thanks.
If you want to have an image, that is supposed to fill the screen it is best to use 9-patch images. This way your image can automatically scale to fit the device. Because even if an image has the correct density, the actual screen size can vary. For example a smartphone and a tablet can both be hdpi, but have completely different screen sizes (and actual pixel count).
So the easiest way to target most devices, when it comes to images that are supposed to fill up the full width of the screen is to have a 9-patch image and create ldpi, mdpi, hdpi and xhdpi versions of it. This way the image will automatically be choosen depending on the density and then stretched to fit the device.
The android sdk also provides a tool that helps with creating 9-patch images http://developer.android.com/tools/help/draw9patch.html
Last two questions stayed unanswered, I hope "third one's the charm" works :)
I want application that is HDPI use those drawables in folder "drawable-xhdpi" and LDPI devices those in "drawable-mdpi". So I don't have to duplicate same images. Is this possible?
Yes, Android scales drawables, selecting the drawable that will produce the best result. But not all scaling combinations work that well. Downscaling to MDPI can produce noticeably poor results. XHDPI to HDPI generally produces pretty good results. But given that the overwhelming majority of devices these days are HDPI, it's probably worthwhile to have HDPI resources. HDPI to XHDPI scaling is not terrible. Some 1280x720 devices uses XHDPI resource. These generally look ok. Google TV uses XHDPI as well. On a huge screen, scaling errors are visible.
LDPI devices are -- for all practical purposes -- non-existent now.
True that generating scaled resources is an enormous PITA. But, in my opinion, you really need to do MDPI and HDPI. And once you've got that unpleasant workflow down, it doesn't require a lot of extra work to generate XHDPI. For what it's worth, if your artwork is in vector format, the vast majority of resources don't need tweaking for specific resolutions. There doesn't seem to be any compelling need to pixel-align edges of square objects, for example. Usually it's only interior features in complex icons and artwork that benefit from some amount of pixel-pushing.
It's pretty clear that XHDPI is going to be come more and more common. Trust me, you don't want to go back and re-do all your artwork in XHDPI after the fact. My advice: if you intend to still be shipping your app a year from now, suck it up, and do the nasty as you go, while it's still relatively easy.
In my experience, if you place an image in just some of the drawable folders, but not all, the OS will choose the "best" image for the device that you are using, even if it is not exactly the perfect fit. For example, if you put an image called arrow.png ONLY in the drawable-hdpi folder, all devices will use that image for the arrow drawable, and scale it down or up appropriately, stretching or shrinking the image.
That being said, you should be able to accomplish what you want by simply putting your image in the right folders and allowing the devices to choose the correct one. For example, if you were trying to accomplish your task with only one image, arrow.png:
drawable-xhdpi/ -> arrow.png
drawable-hdpi/ -> empty
drawable-mdpi/ -> arrow.png
drawable-ldpi/ -> empty
drawable/ -> empty
If you use the app on an ldpi device, the device will use the mdpi image, as you wanted, because it is closest to the correct resolution. On the hdpi phone, it will use the xhdpi image, because it is again the closest to the correct resolution.
Yes. Android automatically downscales/upscales resources that it cannot find. If you were to only put resources in the XHDPI folder it would just work, Android would take care of resizing them to work in all the other densities.
We should add this code in MainActivity class and copy image to dhpi folder with ic_launcher, ic_launcher2, ic_launcher3 and ic_1 is image name, we can change size: width and height
int array_image[]={R.drawable.ic_launcher,
R.drawable.ic_launcher2,
R.drawable.ic_launcher3,
R.drawable.ic_1
}
Is there a way to have Android select a different image based upon the screen size? According to the docs and my testing, images must be placed in folders like drawable, drawable-mdpi, drawable-hdpi, etc.
These folders however relate to the screen dpi and not the screen size. The layout folders are used to handle different screen sizes but they don't allow you to store images in them. Only xml files.
So if I run my app on two devices with the same dpi but with different screen sizes, the same image gets selected from the same drawable folder. What I really want is for a larger image to be selected for the larger screen and a smaller image for a smaller screen.
Thanks for your help.
Yea, you are right, this is how works Android, by saving different pictures in particular folders (l,m,h and xh -dpi).
Where is your problem?
You want to keep images for all screen resolutions? Its too many of them.
Can you write more specific what you want achieve?
If you have a problem in layouts.xml, just check:
android:scaleType="..."
You can use 9-patch images. A 9-patch image can be stretched without loosing quality. You may refer to the following link for more information http://developer.android.com/guide/developing/tools/draw9patch.html
I have a game which displays a full screen image in the background. At the moment I have one image size (1280x800). This works well on large resolutions but on smaller screens the shrinking somewhat degrades the image. You can see jagged edges and it is noticeably worse than what you could achieve using photoshop software.
I have different image sizes, but I am unsure how to utilize them. I know there are different dpi folders, but you can have resolutions of 480x320 and 1280x768 with the same dpi so I don't think these can be of use here.
I believe you can have different layout files for different screen sizes, but the image is not drawn using xml (and in fact would not be possible for my game).
I can only think that I must create a different file name for each size. Then when choosing which image to use I could take the screen dimensions and select the correct one? I am struggling to see how I can make an image look good on both 240x320 and 1280x800 resolutions.
All of the resource qualifiers in the framework can be applied to drawables, not just the dpi designators. In other words, you could create folders like this to segment your images as well:
drawable-ldpi
drawable-xlarge
drawable-normal
drawable-sw480dp
drawable-sw720dp
Even examples like these work...
drawable-v10
drawable-land
And so on...
You can create as many or as few different qualified directories for your image assets as you think necessary to preserve the quality. The Supporting Multiple Screens article in the SDK docs helps describe most of the qualifiers that best fit scaling image assets.
HTH!