I have a larger image of 1024 x 768. When the image is displayed in the android device as the background image then it gets compressed. Is there any way that the image can be displayed properly in all screen resolution?
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:background = "#drawable/titlepage">
</RelativeLayout>
This is the code that I am using for setting the background image. But since the image is quite large it appears to be compressed when viewed on emulator or device.
Any help will be just great.
You are talking about multiple screen support. You need to make 3 types of images, HDPI, MDPI and LDPI. They have all different aspect ratios as well as different sizes.
Check out my tutorial on this subject, should explain everything.
http://wonton-games.blogspot.com/2010/07/tutorial-multiple-screen-support.html
or a simpler method if you just want to keep your aspect ratio is in your xml file using imageView do this
<ImageView
android:id="#+id/background"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="#drawable/background"
android:adjustViewBounds="true">
</ImageView>
What this does is keep the aspect ratio of the image and fit it to the screen. You will get bars on either side if the aspect ratio doesn't match but this is just a quick shortcut way. You might have to play with layout_width/height to make it fit properly.
What you require is to maintain the resolution of the image, that would be the width:height ratio of the image. i am afraid for a 1024*768 the ratio is 1.33 , such image is meant for desktops. usually mobile devices have smaller ratio (w:h). eg: for Samsung galxy S , it would be 0.5, for Xperia X10, HTC Incredible, it would be 0.562. Android device screen sizes may vary. You need to have a suitable version of your image for each mdpi, ldpi and hdpi versions. Even then there is no guarantee that the image aspect ratio will be maintained. Better still have your image to be a 9 patch image, where you can define which part of the image should be stretched and which should be not, here you can preerve important part of the image.
Make an xml drawable file for the bitmap. You can change the gravity to "fill" You will still have issues with screens that are a different aspect ratio, but you can experiment with clamping, tiling, etc to get the look you want.
http://developer.android.com/guide/topics/resources/drawable-resource.html#bitmap-element
Related
I'm going through a problem in an application here my related to this issue. See if you can help me:
In my case I have a ImageView showing a ruler, and then I need to show this rule in real size, where it does not need to grow or shrink as the screen size or density. Using as a basis my Moto G3, it works perfectly, but when testo other devices, it loses the actual size of a ruler because the image tries to fit the screen size.
The image of the ruler is in PNG and measures 3600px x 155px and has measured up to 30cm, it is within a LinearLayout orizontal. In my Moto G3 visible area it is in 10cm, a larger screen for example it should show a larger area of the ruler (11 to 15cm for example), but it contunua only 10cm in the visual field of the screen, showing that it grows and shrinks as the display settings and density of the device.
Before I had a picture of RAGUA for each resource (xxhdpi, xhdpi, etc), so I decided to migrate it to the assets folder of Android, but still with the same problem.
Do you have a light on how to fix it?
Follows the code:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/rulerPolegada"
android:layout_width="1780dp"
android:layout_height="103dp"
android:layout_marginTop="-10dp"
android:layout_marginLeft="#dimen/left_ruler"
/>
</RelativeLayout>
</HorizontalScrollView>
</LinearLayout>
And as I said, after I image for assets, I started to set it in java:
rulerPolegada = (ImageView) view.findViewById(R.id.rulerPolegada);
rulerPolegada.setImageDrawable(Controller.getImageAssets(getActivity(), "ruler_polegada.png"));
Due to Understanding Density Independence In Android, you can calculate those values as follows
Here is how you can calculate for your device (Moto G3)
30cm = 11.811 in
Moto G3 screen density bucket is xhdpi - 320dpi
320px ~= 1 in
320px * 11.811in ~= 3780px
With this steps you can calculate how big your image should be.
Now, instead of providing different ruler's images for different screen densities, place your high quality image in drawable-anydpi folder, because A drawable in res/drawable-anydpi/ also is valid for any screen density. However, in this case, the -anydpi variant trumps any density-specific variant. due to '-nodpi, -anydpi, and WTF?' article from The CommonsBlog
Unfortunatelly, you can't used calculated values in layout xml file directly - ImageView size needs to be changed dynamically in Java code.
Above solution should give you decent accurancy (it can be diffent by 10%), but you can use DensityMetrics together with default display to get actual horizontal and vertical density, which will help you calculate image pixel size more precisely.
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
// these will return the actual dpi horizontally and vertically
float xDpi = dm.xdpi;
float yDpi = dm.ydpi;
Edit
Calculation for 480dp:
30cm = 11.811 in
density bucket xxhdpi - 480dp
480px ~= 1in
480px * 11.811in ~= 5669px
I'm not sure if you get your answers correct because it appears that previous answers were not satisfied. I had once the same problem - I need this ImageView to have the same size on a plethora of devices without scaling. I solved my problem by providing defined value in dp for layout_width and layout_height
You should read this guide for run in multiscreen
I have been looking around and can't find a positive answer to this. For images, do we use hard-coded dp for the layout width and height or do we use wrap_content? For example, say I have an imageview with an icon as its image. If I use wrap_content, the image is too big, and there is no way to resize it (image was made using xxhdpi in mind). If I set the dp manaully then the image doesn't scale with the device if its screen is larger (or does it, I'm not sure if it still does?).
I want to know the workflow we're suppose to follow, I have read all the documentation but it's vague in terms of scaling images. I have an image for each of the various screen sizes (hdpi, mdpi, etc.).
Questions
If I hardcoded the width and height, does android still use those
images (hdpi, mdpi, etc) for different screen sizes?
Is hardcoding the width and height bad practice, if so, what is the
alternative to resizing the image?
What if we hardcoded the size for each screen resolution? So for
example, I would use 200dp x 200dp for tablets and 100dp x 100dp for
phones when hardcoding the width and height of an image. Is this a
good approach?
What is the best workflow to follow when working with images? Should
I create a different size of an image for each screen resolution?
Should I use one large image and then hardcode the size for each
layout?
Is there a website or program in which I can provide an image and it automatically comes up with the various screen density images? For example, I upload an image and it will give me an mdpi, hdpi, hdpix, and etc images for it. I have looked around, but can only find programs that work with icons, not images.
You should be able to rely on the android system to scale your images appropriately. Check out the Dev docs for various scaling methods
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
I have an application that uses ImageViews to show some pictures. The image sizes are 320x480px.
I use some animation to move these pictures to the center of the screen and when the phone has the resolution of 320x480, it works great.
However, when I tried it on emulator with the resolution of 240*320, there were some problems:
The ImageView is still 320x480 so it looks way too big
The animation that uses the screen resolution can't move the pictures to the center, it is at least 20-30 px off
I learned the when dealing with pictures, Android dynamically changes resolution of them to make the images fit in. How could I set that these images should be resized according to screen resolution?
It's hard to say what's wrong without seeing any code. Android resizes images from res/drawable according your screen resolution (ldpi, mdpi, hdpi, etc.). If you place pictures in res/drawable-nodpi, they will not be scaled. You could also use the density dependent folders res/drawable-ldpi, res/drawable-mdpi, res/drawable-hdpi etc. You should definitely read the docs here.
I believe that android:adjustViewBounds="true" and android:scaleType="fitCenter" is what I needed. The ImageViews are scaled down to 240x320 and the animation works well.
Interesting that the upscaling is not proper. When I used in the emulator at 480x800, my ImageView is scaled up to 480x720 so I get black edges. Any idea for that?
I am trying to understand something. A weird thing that I see is that when I put wrap_content in the width and hight, the image is bigger than the the real px (pixel) size of the image which is inserted. Why is that so?
My code with wrap_content:
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="false"
android:src="#drawable/header" />
and thats my code with exact pixel size of the image:
<ImageView
android:id="#+id/imageView1"
android:layout_width="378px"
android:layout_height="155px"
android:adjustViewBounds="false"
android:src="#drawable/header" />
As you can see, thats the exact pixel size:
Why is that? I thought that wrap_content should wrap the view to the content size so why is it bigger on screen?
If you really need to use the image's pixels as-is, and use the screen actual pixels do the following:
1) Create a res/drawable-nodpi and move your fixed-pixel non-scaling images in there.
2) You then can use wrap_content as layout_width and layout_height, and image pixels will match the device pixels with no upscaling because of dpi.
From http://developer.android.com/guide/practices/screens_support.html, the definition of nodpi :
Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen's density.
A very nice explaintaion for supporting the multiple screens is given at
http://developer.android.com/guide/practices/screens_support.html.
you need to put images in respective folders after scaling.
e.g. if you want 100*100 image then place
75*75 in drawable-ldpi for Low density devices
100*100 in drawable-mdpi for Medium density devices
150*150 in drawable-hdpi for High density devices
200*200 in drawable-xhdpi for Extra High density devices
wrap_content means that you want the image as it as its original size is. i.e if the size of the image is 200*200 then it will show 200*200 and if the image size is 400*400 it will show of the size 400*400.
So the reason you are getting a larger image then what you actually get when you hard code it with real pixels is because of the LARGE SIZE of the image. i.e image is actually large.
From my experience I can say that wrap_content always utilize maximum available size possible. So sometimes it stretch the image & sometimes reduce the size of the image. To use exact image use android:scaleType="fitXY"
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="false"
android:scaleType="fitXY"
android:src="#drawable/header" />
Update after 1st 2 comments:
as per android docs :
You can specify width and height with exact measurements, though you probably won't want to do this often. More often, you will use one of these constants to set the width or height:
wrap_content tells your view to size itself to the dimensions required by its content
fill_parent (renamed match_parent in API Level 8) tells your view to become as big as its parent view group will allow.
In general, specifying a layout width and height using absolute units such as pixels is not recommended. Instead, using relative measurements such as density-independent pixel units (dp), wrap_content, or fill_parent, is a better approach, because it helps ensure that your application will display properly across a variety of device screen sizes. The accepted measurement types are defined in the Available Resources document.
I found the term size itself is important, it autometically resizes the images. thats why I told that from my experience I found sometimes it stretch the image & sometimes reduce the size of the image
You need to see where you put the image. If its in hdpi it will look bigger on screen then if its in hdpi when ising wrap_content. so, in order for it to be the exact size, put it in right library.
I have all my images in the assets file for showing in my andorid app. In order to fit the resolution of most of the android phone, I have created most of the images at size 1280 * 800 with resolution 160 dpi. I am not sure if it's a proper way...
However, when I try to run the app, it seems that the phone could not adjust the image automatically. I would like to ask how to code the program so that the phone could adjust the image according to the phone screen size?
Thank you.
1280 x 800 isn't a resolution that is actually supported by any device. Honeycomb devices (which have that resolution) all allot space for the Action bar and the Status bar, so you need to account for that, if you're trying to make images that are full screen. You can set your images to preserve their aspect ratio, and then set them to fill parent vertically and wrap content horizontally (or vice versa) and you will wind up seeing them looking like they scale correctly, and leave them at 72dpi The devices will display them correctly.
<ImageView
android:adjustViewBounds="true"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
/>
I am not sure if it would help but its better to use dip (density independent pixel) instead of dpi, where the latter depends on the screen density and the former doesn't.