I have created a dress up game app. After the user finishes dressing up his character, he/she can save it to the app's gallery.
I am using canvas and drawbitmap on canvas to generate the final image, which is then shown on the app's gallery. The xhdpi image size should be 600x900 pixels. When this image is shown in the normal android gallery, it is shown as 600x900 and it (got from info) looks big enough. However, when I show it in my app, it looks much smaller though the ImageView is set to wrap_content. Moreover, when dressing it up, it is also set to wrap_content and it looks bigger than the one in the app's gallery.
My theory is that because I'm trying to set it programmatically using
.setImageDrawable(Drawable.createFromPath(path));
and because the screen is xhdpi, it is dividing the size by two.
What can I do?
Likely, you're testing on a device that is not xhdpi, but hdpi or mdpi.
When you provide a graphic in a density bucket, Android will take care of resizing that image so that it remains the same physical dimension across all devices (that is to say, size in cm on the screen).
If you would like to use the raw drawable, you can provide the graphic in the res/drawable-nodpi folder.
If you would like to retain the density buckets, but your graphic is too small, provide the correct sizes in res/drawable-mdpi, res/drawable-hdpi and res/drawable-xhdpi.
I don't believe there is any way of preventing this behavior through Drawable.createFromPath(). You could load the bitmap directly using BitmapFactory and provide it into the ImageView using setImageBitmap():
File f = new File(path);
Bitmap b = BitmapFactory.decodeFile(f.getAbsolutePath());
imageView.setImageBitmap(b);
Related
how to use vector images which scale up and down according to the screen sizes?
I m using a vector image in my project but it is not scaling in big screens.
what you mean by being scaled ? maybe you are misunderstanding.
if you mean the image size would be changed in various screen sizes such thing wont happen. the image size is what you provide in your imageview (or any otherview using the image).
the only different between vector assets and normal asset is that vector asset are redrawn every time so you wont have a low quality image no matter how big it is and which device it is being shown in. so you wont need to save various size of image for various size of screens.
if you want to change the size of image just change the imageView height and width. you can use dp (density independant) unit.
you dont have to do anything for support vector images for diffrent screens its already scale for the relevant dp, Can you give more details about your problem when you say "it is not scaling in big screens?"
maybe you want the image on tablets will be bigger?
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 calculate inSampleSize to use Bitmap decode method to resize large png files.
When creating a this new bitmap and Log info it's width and height with .getWidth() and .getHeight(), its pixels count has grown by 3 relative to its original size.
code: from line 121-204
https://github.com/abisai1221/android-bitmaps/blob/master/png%20to%20bmp
all help is greatly appreciated.
I would bet on screen density being applied. When you load bitmaps from resources, you have to put them in right drawable folders, because Android will automatically scale them to match your phone's screen density. Each folder should contain only images for one specific density. For example, if you have a high density screen in your phone, you should put images in drawable-hdpi folder to get them without scaling. If you're getting 3 times larger images, you probably have a very dense screen, like Nexus 5 or recent Galaxy S phone. To disable scaling, put images in drawable-nodpi folder.
I saw another post of resizing issues and came across the ".inScaled" field of BitmapFactory.options.
This executes by default to scale bitmap to target density.
I set this field to false to prevent it from executing and the images come out perfectly, tho Im still confused as to why it scales the image by a factor of 3.
When you get a bitmap from a resource for example with:
Bitmap src = BitmapFactory.decodeResource(getResources(), R.drawable.yourimage);
It is automatically scaled depending on the device's screen density. How can I avoid that and retrieve it in its original pixel size whatever the screen density is?
Thanks
What do you mean "It is automatically scaled"? When you call this method Android takes image from folder res/drawable-?dpi - depending on device where app is running. If your ldpi folder contains 30*30px image, mdpi contains 40*40px image and hdpi contains 60*60px, you will get bitmap one of this sizes(depends on device). Android does not change anything.
If you see that on the screen your image scaled somehow, check properties of ImageView.
I am trying to understand screen sizes and densities and what I really need to do in order to make my multiple choice question game work on every Android screen nicely. I want my game to look the same in every screen size and density meaning no changes to the layout and good looking images.
Basically my game displays questions which are png files, and answers to choose from which are also png files. I specify each imageview size and imagebutton in dp, and the locations of these on the screen in dp. For my layout background image I just have it fill parent width and height.
So my question is why can't I just have one drawable folder with hdpi images? Therefore, the images would be scaled appropriately in dp on all screen sizes and located in the same place and look the same on every screen. And the images would look good on hdpi screens and smaller ones? Also, why can't I just have one layout folder with the same explanation?for your answers!
You can create the only one folder but the images in that must be .9.png bcoz these images stretched according to the screen. Another way is create the different size images and place them in the hdpi,mdpi,ldpi folders.
You can create only one folder for both ressources. But for image, if you dont want to get uggly stretched image you should create 3 image size with different dpi for each folder. Your picture will be sharper for hight dpi screen and faster for low dpi screen with a picture near the final size.