Android - How to enlarge a bitmap - android

I usually download images that are larger in size and shrink them using an imageview but lately Im trying to deal with my apps not working on a lesser network connection so I was wondering how can I increase the size of an image once it gets to the device. I tried resizing the image once it was in an imageview but the imageview will get no larger than the original image. Im sure theres a really easy way to increase or blow up an image on the device but I havent come across it yet.
So.....how can I increase the size of an image. Id like to blow it up and use it in an imageview but the images Im dealing with are only 128X256 and Id like to expand them to about 512X1024.

Try using this method:
public static Bitmap scaleBitmap(Bitmap bitmapToScale, float newWidth, float newHeight) {
if(bitmapToScale == null)
return null;
//get the original width and height
int width = bitmapToScale.getWidth();
int height = bitmapToScale.getHeight();
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(newWidth / width, newHeight / height);
// recreate the new Bitmap and set it back
return Bitmap.createBitmap(bitmapToScale, 0, 0, bitmapToScale.getWidth(), bitmapToScale.getHeight(), matrix, true); }
refer to my answer in: ImageView OutofMemoryException

Use matrix to resize the bitmap.
Check this
Resize Bitmap

If you want to scale the Bitmap manually, there is a Bitmap.createScaledBitmap() method that you can use for this.
If you want the ImageView to handle this, you have to set the layout_width/layout_height to something other than wrap_content or it will always shrink to the size of the Bitmap. Then you need to change the scaleType attribute to a type that actually scales the bitmap.

The functionality to scale image up or down is readily available via android.graphics library:
Bitmap bitmapScaled = Bitmap.createScaledBitmap(Bitmap bitmapOrig, int widthNew, int heightNew, boolean filter);

Related

Crop bottom portion of a bitmap programmatically

I have a bitmap taken from a camera. I want to crop the image so it only leaves the bottom portion of it. The cropped image should be 80% less the height of the original bitmap, so I want only the 20% of the bottom part starting from the left edge.
I'm doing this explicitly in the code without any Android cropping intent whatsoever.
An image to visualize what I want to achieve:
I've managed to crop the top part of the bitmap by using this code:
final Bitmap toBeCropped = BitmapFactory.decodeFile(mFile.getPath());
final BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inTargetDensity = 1;
toBeCropped.setDensity(Bitmap.DENSITY_NONE);
int fromHere = (int) (toBeCropped.getHeight() * 0.2);
Bitmap croppedBitmap = Bitmap.createBitmap(toBeCropped, 0, 0, toBeCropped.getWidth(), fromHere);
mPreviewHalf.setImageBitmap(croppedBitmap);
But I couldn't find a way to start the cropping 80% from the top. I'm thinking of getting the y-coordinate of the Bitmap, so that I could crop any image sizes and always get the bottom portion only. But can anyone point to me how do I get this coordinate from a bitmap? Or do I have to take it from the layout itself?
I am not familiar with operations on Bitmaps but from inspecting your code and looking at the API my guess would be that you need to specify the y coordinates on the following line to match the starting point:
Bitmap croppedBitmap = Bitmap.createBitmap(toBeCropped, 0, "here", toBeCropped.getWidth(), fromHere);
So my guess would be something like the following:
Bitmap croppedBitmap = Bitmap.createBitmap(toBeCropped, 0, (toBeCropped.getHeight() * 0.8), toBeCropped.getWidth(), fromHere);
in this case fromHere will define the number of rows you want to crop not the starting point (which is 20% of the total as you have pointed out)
This is how I do it:
topcutoff is what you want to cut of on top of the image and buttomcutoff on the buttom (if needed)
height = height - topcutoff;
height = height - bottomcutoff;
croppedBitmap = Bitmap.createBitmap(croppedBitmap, 0, topcutoff, width, height);
Basically you just set a startpoint (topcutoff) from where to begin displaying the bitmap. In your case this would be the position after 80% of your bitmap.
This might also explain some things: Google Bitmap Documentation
"int: The y coordinate of the first pixel in source", so where you want to begin displaying your image.

How to get scaled bitmap with respect to screen size with out getting Out of memory exception

In my activity I am creating a Bitmap of the width and height same as the device resolution (width and height )
what I am doing
Bitmap mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
Bitmap.Config.ARGB_8888);
and screenWidth and screenHeight is
screenHeight = displaymetrics.heightPixels;
screenWidth = displaymetrics.widthPixels;
Now if I make this bitmap I get my heap goes up to 19mb , which is not so good.
So tell me 2 things
1. What is a good way of creating the bitmap with respect to screen with and height with minimum memory consumed
2. How can I destroy the bitmap after using it ?
Please provide me a little source code or link of source code.
What is a good way of creating the bitmap with respect to screen with and height with minimum memory consumed ?
Never ever create a Bitmap with the screen height or width, because that will be very huge based on the density of the device.Instead use the height and width of the screen and calculate the aspect ratio. Now fix the height to a constant value (like 1200px) and then calculate the width based on the aspect ratio. The ImageView or any other view will scale this properly.
If you really want transparency then use Bitmap.Config.ARGB_8888, if not could use RGB_565 or something else from the list here: http://developer.android.com/reference/android/graphics/Bitmap.Config.html
Follow below points if you are not creating a fresh bitmap but decoding the bitmap from some resource:
You need to use BitmapFactory.Options.inSampleSize to reduce the sampling. So how to calculate the inSampleSize if you already know the height and width? Refer this here: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
So you do all this, and still the inSampleSize is not high enough and you get the OutOfMemoryError ? Don't worry, if this is the case, you need to catch this OutOfMemoryError and in that increase your inSampleSize and do the bitmap decode again. Put this logic in a loop, so the crash never happens.
How can I destroy the bitmap after using it ?
This is really simple. Make sure to call the Bitmap.recycle() method. And remove all reference to the bitmap. Once you do this, the resource will be released and GC will do the cleaning up.
UPDATE: When you create the a bitmap with screen_width and screen_height you would end up with a huge bitmap. Instead create a less resolution bitmap that fits the whole screen. You can see the following code on how this is done.
float screenHeight = displaymetrics.heightPixels;
float screenWidth = displaymetrics.widthPixels;
float aspectRatio = screenWidth/screenHeight;
int modifiedScreenHeight = 1000;
int modifiedScreenWidth = (int) (modifiedScreenHeight * aspectRatio);
Bitmap mBitmap = Bitmap.createBitmap(modifiedScreenWidth, modifiedScreenHeight, Bitmap.Config.ARGB_8888);
Now you got the bitmap with the right aspect ratio. You could use this bitmap as it is in the ImageView to fill the whole screen. Make sure you put android:scaleType="fitXY" for the ImageView.

How to properly set a wallpaper on Android

It seems that setting a wallpaper on Android just doesn't work in any useful way.
If you get an image from your phone and set it as the wallpaper, it's way too big for the screen
If you resize it (either using a createBitmap() function that allows you to specify size, or the ridiculously useless createScaledBitmap()) it goes all jaggy and out of focus
If you use some freaky hacks to fix the quality of the image, it's better, but still not perfectly clear by any stretch.
If you attempt to get the current wallpaper and set that, it still seems to make it too big. It appears to give you the original image file, forcing you to resize it, which doesn't work.
Now, the phone's internal software is perfectly capable of resizing an image to be smaller with no reduction of quality. Why does it not share this functionality?
WallpaperManager wallpaperManager = WallpaperManager.getInstance(Spinnerz.this);
// gets the image from file, inexplicably upside down.
Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "DCIM/Camera/Zedz.jpg");
// use some rotation to get it on an angle that matches the screen.
Matrix bitmapTransforms = new Matrix();
bitmapTransforms.setRotate(90); // flip back upright
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),bitmapTransforms, false); // create bitmap from bitmap from file, using the rotate matrix
// lets set it exactly to the resolution of my Samsung Galaxy S2: 480x800 pixels.
// This function appears to exist specifically to scale a bitmap object - should do a good job of it!
bitmap = Bitmap.createScaledBitmap(bitmap, 480, 800, false);
wallpaperManager.setBitmap(bitmap);
// result is quite a jaggy image - not suitable as a wallpaper.
PIC:
Try this ,
Display d = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = d.getWidth();
int height = d.getHeight();

Scaling image in Android

I tried to scale an high-resolution image to the desired size of my android and then set it as wallpaper, but as result I have a scaled image with 'annoying alternate rows' that make the picture NOT attractive.
int newWidth = wallpaperManager.getDesiredMinimumWidth();
int newHeight = wallpaperManager.getDesiredMinimumHeight();
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmapOrg, newWidth, newHeight, true);
You are scaling the bitmap correctly.
You could try downloading GIMP (free software) and scale your image to match the main 3 resolutions of android phones. This may produce a better result.

Memory efficient image resize in Android

I am trying to reduce the size of images retrieved form the camera (so ~5-8 mega pixels) down to one a a few smaller sizes (the largest being 1024x768). I Tried the following code but I consistently get an OutOfMemoryError.
Bitmap image = BitmapFactory.decodeStream(this.image, null, opt);
int imgWidth = image.getWidth();
int imgHeight = image.getHeight();
// Constrain to given size but keep aspect ratio
float scaleFactor = Math.min(((float) width) / imgWidth, ((float) height) / imgHeight);
Matrix scale = new Matrix();
scale.postScale(scaleFactor, scaleFactor);
final Bitmap scaledImage = Bitmap.createBitmap(image, 0, 0, imgWidth, imgHeight, scale, false);
image.recycle();
It looks like the OOM happens during the createBitmap. Is there a more memory efficient way to do this? Perhaps something that doesn't require me to load the entire original into memory?
When you decode the bitmap with the BitmapFactory, pass in a BitmapFactory.Options object and specify inSampleSize. This is the best way to save memory when decoding an image.
Here's a sample code Strange out of memory issue while loading an image to a Bitmap object
Are you taking the picture with the camera within your application? If so, you should set the picture size to a smaller one in the first place when they're being captured via android.hardware.Camera.Parameters.setPictureSize
Here is a similar question that I answered and show how to go about dynamically loading the proper image size.
out of memory exception + analyzing hprof file dump

Categories

Resources