I have a view that I am drawing to a bitmap, saving to disk and then putting in an ImageView via setImageURI. However, when the image is displayed in the ImageView it is not being shown at the correct size. It is about 1/3 smaller than it should be. I'm guessing that this is a density issue, but I can't figure out what's going wrong (my emulator is WVGA). Ideas anyone?
I ran into this issue today too. I ended up loading a bitmap instead.
Bitmap bit = BitmapFactory.decodeFile(image_path);
mImageView.setImageBitmap(bit);
Which displays correctly.
You're right
This is a density issue. To ensure that your image displays in the correct dimensions regardless of the density of the device you should consider using dip (density independent pixel) units.
Also, Android 1.5 does not support image density -- ie. it doesn't know how to distinguish between mdpi, hdpi, ldpi bitmaps. Android 1.6 and above does. You can use Bitmap.setDensity() or BitmapDrawable.setTargetDensity()
Finally -- you mention it is 1/3 small that it should be which is a good indication that the problem is related to density as mdpi density is 160dpi and hdpi is 240dpi -- 160/240 = 2/3 which is 1/3 less than your original image.
Hope this helps!
Try this:
ImageView photo = (ImageView)findViewById(R.id.photo);
photo.setScaleType(ImageView.ScaleType.CENTER);
Related
I'm trying to make an activity with an image that is the same height as the screen. I tried going to easy route, and just using a really big image and then scaling it down within the app, but when I run it on a device with a smaller screen, I get an error saying the device ran out of memory. I was hoping to make several drawable folders for each dpi (drawable-mdpi, drawable-hdpi, etc.). I looked up the pixel dimensions for splash screens, but when I resize my image to fit those dimensions (https://stackoverflow.com/a/15744389/5909429), the image only fills about half the screen on my smaller device.
What dimensions should I actually use, or am I using the drawable folders wrong?
[...]or am I using the drawable folders wrong?
Yes and no. I don't know about any "perfect" values for your picture dimensions, and I doubt that there are any, due to the fact that there are too many different phones to support.
The usage of dpi ensures that everything has the same size. If you were to put a ruler on your screens on a xxxhdpi and a ldpi device, both pictures would be the same size. This is dpi.
What you are trying to do is filling a phone screen. This has not much to do with dpi, but is about the actual pixel size of the screen. If you have a 1920x1080 phone display, you want an image with the same resolution. This does not say anything about dpi or screen density, and it has frankly nothing to do with it.
To properly scale down your image—and not running into OOM—you can either use a designated image loading library, like Glide, or Picasso, or you can take a look at BitmapFactory which lets you supply a inSampleSize to load the image in the size needed yourself. The official documentation can be found here at Loading large bitmaps efficiently.
I am wondering what would happen if you put for instance one image in only one specific size, let's say image X in hdpi and an other image Y in only resolution size xxhdpi, the size which was "right" for the device was xhdpi. Assuming that the OS decided what was the "right" size for the device.
Will it then downscale the image xxhdpi and upscale hdpi to xhdpi? Or would it only change the size of one image, for instance the one with the lowest resolution remains the same, the higher ones are downscaled?
Quite an interesting question out there!
In this case, the bigger drawable will be taken an downscaled to the device needs.
However, if the device is i.e. xxhdpi and you provide drawables ie. for mdpi and hdpi, the OS will take the hdpi drawable and scale it UP.
Android chooses the one appropriate for the resolution or screen dimensions. ..when it doesn't find one in the right folde than it goes down in the resolution searching for a lower quality folder...again when it doesn't find one in the folder with lower resolutions than it searches in the higher quality....and crashes if there is also none at runtime....AT compiletime you'll get error when thers n no image
Depends on how you display the images....Icons get everytime up or down scaled. ...IT is recommended that you have one and only one xxxhdpi icon in your app because downscaling is better than up scaling due to AA
Ok so I know questions about resources for different densities have already been asked, however I ran into a problem, which is why this question is different. Ok so on the android developers website here http://developer.android.com/training/multiscreen/screendensities.html it's stated to use the scale of 1.0 for mdpi, 1.5 for hdpi, 2.0 for xhpdi, and so forth. But the problem is this scale appears to be wrong. If I make an image that is 480x800 for the nexus 1, it will take up the entire screen. If I divide this by 1.5 to get the mdpi version which is the baseline, I will get 320x533.34 approximately. Now lets try multiplying this by 2.0 to get xhdpi version. You will get 640x1066.68. In other words, on a nexus 4 with xdpi and resolution of 768x1280, the image will NOT take up the whole screen. The scaling is not accurate. So I made an image that takes up the whole screen of the nexus 1, then scaled it according the the scale given by the android developers, and for other screens the image will not take up the whole screen. I want a scale that will give me complete accuracy. Thanks!
In other words, on a nexus 4 with xdpi and resolution of 768x1280, the image will NOT take up the whole screen
It is not supposed to. Density has nothing to do with screen size. I can have an -xhdpi screen that is one inch, one foot, one meter, one mile, or one parsec in diagonal length. Those screens would have drastically different resolutions, but the density would be the same.
MDPI is 1.0 as you said, not 1.5. If you create an image that is 480x800 in the MDPI folder, it will be scaled up to 720x1200 on an HDPI device, or 960x1600 on an XHDPI device. You're never going to get an image which properly fits all screens -- there are just too many aspect ratios and resolutions to do that properly. Try to avoid that design philosophy altogether if possible (e.g. maybe have a nine-patch image in the center with a stretchable region on the edges), or set the image to scale and crop to fit (e.g. scaleType="centerCrop") and keep important parts of the image away from the sides of the screen to allow for some wiggle room.
I am having a big trouble in resizing my images for Android image sizes, ldpi (120 dpi), mdpi(160 dpi), hdpi(240dpi), xhdpi(320 dpi) and nodpi using Photoshop, because I don't know how to convert my images to these size. As you know, Photoshop has no DPI stuff to work with. So, what I actually need is to convert my images to ldpi,mdpi,hdpi and xhdpi sizes using Photoshop.
So, how can I convert these images to the Android deserved sizes?
Have you tried using Illustrator? The psd files can also be worked with it.
You could also use Inkscape or other free tools.
Check this: http://envyandroid.com/archives/271/easiest-way-to-create-android-icons
Hope this helps.
The answer is right there in your screenshot. Photoshop uses Pixels/Inch which is the same as DPI (well mostly, anyway).
To achieve what you are trying to do, simply alter the Pixels/Inch in the Image Size dialog to your DPI value - start with 320dpi, since shrinking images will look better than enlarging them. After altering the value you will notice that your width and height values (Pixel Dimensions) are changed, change them back to the desired resolution for your 320dpi image (make sure that you use a sufficiently large resolution for 320dpi).
Now create your image for this resolution. Once you are complete, open the Image Size dialog again. Now all you need to do is alter the Pixels/Inch value to the remaining DPI values (240, 160, 120) and your image will be scaled down (notice how the width and height for Pixel Dimensions will get smaller with each decrease in DPI).
If you have no idea about the starting resolution you can use the width and height under Document Size to set the actual resolution. For example, the Nexus 4 is a 320ppi device (mostly) and has a screen size of 4.7" (5.27x x 2.70x), so if you use a width of 2.635" and a height of 1.35" it should cover 1/4 of it's screen (half of width and half of height).
I am using image say 85x85 px (putting this image in drawable-mdpi)
and if i am displaying this image of 85x85 px on [320x480]mdpi screen size device it looks good,
but while displaying this image on [480x800]mdpi device it looks very small.
I wants to know how can i resize this image of (85x85 px) so that it works fine for the device having screen width and height of 480x800, mdpi.
You have to set the image size in the xml in dp. This post is really helpful.
Consider MDPI image(let say 85x85) as baseline Create images as follow
FOLDER ImageSize Percentage
LDPI 64x64 75% of baseline
MDPI 85x85 100% BASELINE
HDPI 127x127 150% of baseline
XHDPI 170x170 200% of baseline
The better solution for this is to produce LDPI,MDPI,HDPI,XHDPI,XXHDPI sized images and place it inside the corresponding folders.
Put the image in /drawable, and define the size of the image in your XML as 85dp, it will then be scaled for LDPI/HDPI/XHDPI/XXHDPI and god forbid XXXHDPI.
However, the better solution would to produce HDPI(128px)/XHDPI(170px)/XXHDPI(255px) version of the graphics and put them in /drawable-hdpi, /drawable-xhdpi, /drawable-xxhdpi respectively. This way you can provide the best experience for your users.
[Edit]
"dp" is Android's way of defining physical size of an UI objects, so a button of 48x48dp will have roughly the same physical dimension even when run on screen sizes between 240x320 to 1080x1920, for more information check Android developer site's Supporting Multiple Screens.
[Edit 2]
For images on canvas you can use this to calculate the scaled size of the image:
DisplayMetrics dm = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(dm);
int newSize = (int)(85 * (dm.densityDpi / 160f));