Resize a bitmap eficiently and without losing quality in android - android

I want to reduce the size of an image on disk without losing quality. I don't want to change the width and height of original image.
I want to do something like https://tinyjpg.com/
It reduces the size of image without changing the width and height of image.

You need to compress with jpeg, if you want to reduce size without change measurements. Try this;
String file = ...
OutputStream s = new FileOutputStream(file);
BitmapFactory.decodeFile(file).compress(CompressFormat.JPEG, 80, s);
s.close();
80 is compression factor which between 0-100 (0 lowest quality, 100 highest quality). Try to find best for your situation.

Related

inSampleSize vs createScaledBitmap?

AFAIK, the inSampleSize attribute of BitmapFactory.options will read a sampled image as per the inSampleSize value. Eg: If value is 4, it will effectively read 1/16 pixels and thus memory required to load it will drastically reduce.
Here in fact, it is maintaining the aspect ratio in the sense that it has skipped 1/4th pixels along height and 1/4th pixels along the width.
When I load this bitmap in a smaller ImageView, aspect ratio is maintained and it looks good. I have used the following formula to derive the inSampleSize = max(Width/reqWidth, height/reqHeight)
size of the imageview = 100dp * 100dp, I have converted 100dp to pixels as per the screen density and used that result as the reqWidth and reqHeight.
(Note: All my images are bigger than the reqWidth and reqHeight)
However If I apply another operation Bitmap.createScaledBitmap() on above reduced version of bitmap, the image gets stretched and does not look good in the View.
I am not able to understand what createScaledBitmap() exactly does?
Given a Bitmap, let's call it bmp1, the create Scaled bitmap method creates a new Bitmap from bmp1 which is upscaled/downscaled to a new size.
However, since you're doing the scaling yourself, perhaps you should simply call createBitmap() instead? That one will respect the new size you tell it to be, and won't scale the original image, which is what you want from what i understood.
Please correct me if I'm wrong, however.

How to calculate selected image size in gallery?

Have edited my question to make it more clear.
Basically I am working on an App where users need to upload their profile image. However I need to limit the size of the image upload to less than 4MB. Here where user selects his image from the image gallery, at that very instant I need to check the image file's size and show an alert to the user if the file size is greater than 4MB and restrict the upload.
Presently I am using this code to get the file size:
File Img = new File(selectedImage.getPath());
int length = Img.length();
I know length() returns file size in bytes, however even after conversion from bytes to MB, this always seems to return very small values than the original image file size leading to me believe that getting the file size this way is inaccurate.
Is there any other way I can get the file size of the image files from the device gallery?
Any help is much appreciated. Thanks guys.
Actually, the question is little bit unclear: size is 'in Kb' or youhave to know how would it seen on the screen??
Will that help?
Determining image sizes for multiple android screen sizes/densities
Android screen sizes in Pixels for ldpi, mdpi, hpdi?
Here's how to get dimensions from a drawable resource with BitmapFactory:
BitmapFactory.Options o = new BitmapFactory.Options();
o.inTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
Bitmap bmp = BitmapFactory.decodeResource("Your image file");
int w = bmp.getWidth();
int h = bmp.getHeight();

Image size issue when loading from external storage on Android

I would like to display an image from external storage which is 72x72 px.
My device has high density.
The image view height and width are "wrap_content".
I got different results if I load the image or use an URL.
If I use an URL like this then the result will be about 48x48px.
imageView.setImageURI(Uri.fromFile(file));
If I load the bitmap the result is 72x72 px as expected:
InputStream is = context.getContentResolver().openInputStream(Uri.fromFile(file));
Bitmap b = BitmapFactory.decodeStream(is, null, null);
is.close();
iv2.setImageBitmap(b);
You can see the results here:
It would be better if I could use the setImageURI and not to preload
the image and I would like to display the image in appwidgets too.
Can you tell me what cause the difference and how can I avoid it?
try by this i think it work
either change in xml file in imageview by
android:scaleType="centerCrop"
android:adjustViewBounds="true"
or either use in java code
image.setAdjustViewBounds(true);
image.setScaleType(ScaleType.CENTER_CROP);
either use "centercrop" or "fitxy" may it also works
If both images have different sizes and you can't change the image size you have to set in your xml the image width and height to for example 72dp. You shouldn't use px, but dp because otherwise it wouldn't display good on different phones.

Behaviour of ImageView when scaled

I do some operations with my Views that scale then trough:
imageView.setScaleX(2);
imageView.setScaleY(2);
On that ImageView I put a image that is two times greater than it, as expected when the scale is 1, the Bitmap is scaled down to the view size, my question is:
When the view is scaled up, the portion of the bitmap I see is the original image or the scaled-down image scaled up.
The difference is that if a tiny image is scaled up we lost contrast on letters, if it's the original image it wont.
When you scale an image up you're loosing quality. In you're case, you're doubling the width and height therefore, for each pixel you get 4 pixels assigned to it. The extra 3 pixels won't give you the quality you wanted.
If you want to go back to the original size you should decode the source again. This way you'll get the quality you're looking for.

android - query CAMERA folder images with width and height

is it possible to query for images from CAMERA folder with height and width?
I am querying it with only URL right now. I want to avoid loading image into Bitmap and I need to have width and height of it beforehand so I can figure out proper scaling. Right now some of the photos I load can be really large size and some can be tiny. If I set same scaling on them they don't look right. Small images get resized for no reason. Knowing width and height would solve this. Also I cannot sample load a bitmap because that causes memory issue when images are really large, like those taken with 3 megapixel camera.
Here is how I load them:
https://stackoverflow.com/questions/5710036/android-camera-folder-images-not-all-show-up
Thank you.
You should do decoding for the image without getting its whole data.
the reason it doesn't exist on the DB is that the user can always modify the images to have different dimensions than the original one.
in order to get just the minimal information of the bitmap, use something like:
public static BitmapFactory.Options getBitmapOptions(final String filePath) {
final BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, bitmapOptions);
return bitmapOptions;
}

Categories

Resources