I have following situation:
I have ImageView and Bitmap inside it.
The problem is that
I don't know the dimensions of bitmap (not physical size, size that it takes on screen)
or
I need ImageView not to be bigger that this Bitmap on the screen.
ImageView's background has black color on below snapshot.
You can make sure the image view isn't bigger than the bitmap by setting its layout_width and layout_height to wrap_content on your imageView tag in its xml file.
You can also use its scaleType to affect how the image should be manipulated to fit the imageView.
You can also just access the bitmap's width/height properties to get its dimensions.
EDIT::
You can convert your bitmap into a byte[] and resize it using the following helpers:
/**
* Resize an image to a specified width and height.
* #param targetWidth The width to resize to.
* #param targetHeight The height to resize to.
* #return The resized image as a Bitmap.
* */
public static Bitmap resizeImage(byte[] imageData, int targetWidth, int targetHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = calculateInSampleSize(options, targetWidth, targetHeight);
options.inJustDecodeBounds = false;
Bitmap reducedBitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length, options);
return Bitmap.createScaledBitmap(reducedBitmap, targetWidth, targetHeight, false);
}
private static int calculateInSampleSize(BitmapFactory.Options options, int requestedWidth, int requestedHeight) {
// Get the image's raw dimensions
final int rawHeight = options.outHeight;
final int rawWidth = options.outWidth;
int inSampleSize = 1;
if (rawHeight > requestedHeight || rawWidth > requestedWidth) {
final int halfHeight = rawHeight / 2;
final int halfWidth = rawWidth / 2;
/*
* Calculate the largest inSampleSize value that is a power of 2 and keeps both
* height and width larger than their requested counterparts respectively.
* */
while ((halfHeight/inSampleSize) > requestedHeight && (halfWidth/inSampleSize) > requestedWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
Related
So I am using zetbaitsu/Compressor library for image compression and resize the image but when I try to compress the image dimension of original dimension (3503 x 5254) the result for the following height value are as follow
800,700,600 will give the resolution of (876 x 1314) which is 1/8 of the original size and
when the value is 900+ the resolution of the image gets (1752 x2627) which is 1/2 of the original.
So is there any way to change the size exactly as per our standards as I tried other similar question i was not able to get the desired results.
It's actuallly only possible by creating your own custom constraint for this library.
The usual resolution constraint of this lib (Methodcall)(Method declaration) uses the following method (found here):
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
So it reduces the size of the image by 2 as long as it is bigger than the requested size.
The easiest way to change this is probably to create your own custom constraint and change the calculateInSampleSize() call to your own method calculating the modifier for the exact size.
Edit:
This is a sample constraint, how it should work. I couldn't test so far, but this should give you an idea how it works:
public class SizeContstraint implements Constraint
{
private int _height;
// Resulting image height
public SizeContstraint(int height)
{
_height = height;
}
// Checks, if the constraint is valid
#Override
public boolean isSatisfied(#NotNull final File file)
{
// Get the file options (height, width, e.t.c)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
// Calculate if the current image is bigger than the necessary size
return calculateExactSizeModifier(options, _height) > 1;
}
// This method is only called, if the constraint is invald (the image is too big)
#NotNull
#Override
public File satisfy(#NotNull final File file)
{
int height = _height;
int width = 0;
// Get the file options (height, width, e.t.c)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
// Get the size modifier to be able to resize the image
int modifier = calculateExactSizeModifier(options, height);
// Calculate the width using the modifier
width = options.outWidth / modifier;
// Resize the file into a bitmap
Bitmap bmp = id.zelory.compressor.UtilKt.decodeSampledBitmapFromFile(file, width, height);
// Write the bitmap back into the file
return id.zelory.compressor.UtilKt.overWrite(file, bmp, Bitmap.CompressFormat.JPEG, 100);
}
private int calculateExactSizeModifier(BitmapFactory.Options options, int reqHeight)
{
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int modifier = 1;
// Calculate modifier if height bigger than requested height
if (height > reqHeight)
{
modifier = height / reqHeight;
}
return modifier;
}
}
I am struggling with showing the proper sized images in two of my activities.
The image in the CatalogActivity looks like it is properly scaled down and then cropped while the image in the EditorActivity is whole and is much smaller.
The only difference is that the image in the catalog comes from image resource while the editor image comes from the gallery so from Uri.
Could you tell me why is this difference and how to make the image from EditorActivity the same as the other one?
From CatalogActivity:
// Make the sample image smaller so it doesn't take too much space in the memory
Bitmap sourdoughBitmap = ProductsEntry.decodeSampledBitmapFromResource(getResources(), R.drawable.sourdough_picture, 72, 72);
From EditorActivity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == RESULT_LOAD_PICTURE && resultCode == RESULT_OK && null != intent) {
Uri selectedPictureUri = intent.getData();
// Show the selected picture in an ImageView in the editor
try {
// Scale the bitmap received from the uri so it fits in the small ImageView
scaledPictureBitmap = ProductsEntry.decodeSampledBitmapFromUri(this, selectedPictureUri, 72, 72);
// Hide the gray picture placeholder
mImageView.setBackgroundResource(0);
// Show the scaled bitmap in the ImageView
mImageView.setImageBitmap(scaledPictureBitmap);
// The user has chosen a picture and we can change
// the text of the button to say "Change picture"
mAddPictureButton.setText(R.string.edit_product_change_photo);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
From ProductsEntry:
/**
* Helps create a smaller bitmap image from resource
* #param resources - a resources object
* #param resourceId - the id of the image in the drawable folder
* #param requiredWidth - the width that we want for the final image
* #param requiredHeight - the height that we want for the final image
* #return the decoded Bitmap
*/
public static Bitmap decodeSampledBitmapFromResource(Resources resources, int resourceId,
int requiredWidth, int requiredHeight){
// First decode with inJustDecodeBounds = true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(resources, resourceId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, requiredWidth, requiredHeight);
// Decode bitmap with inJustDecodeBounds = false
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(resources, resourceId, options);
}
/**
* Helps create a smaller bitmap image from a uri
* #param context - a context object
* #param uri - the uri of the image
* #param requiredWidth - the width that we want for the final image
* #param requiredHeight - the height that we want for the final image
* #return the decoded Bitmap
*/
public static Bitmap decodeSampledBitmapFromUri(Context context, Uri uri, int requiredWidth, int requiredHeight)
throws FileNotFoundException {
// First decode with inJustDecodeBounds = true, only to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri), null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, requiredWidth, requiredHeight);
// Decode bitmap with inJustDecodeBounds = false
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri), null, options);
}
/**
* Calculate a sample size value that is a power of 2 based on a target width and height
* #param options is used to pass options to the BitmapFactory
* #param requiredWidth is the width that we want for the final image
* #param requiredHeight is the height that we want for the final image
* #return by how much to scale down the image
*/
private static int calculateInSampleSize(BitmapFactory.Options options, int requiredWidth, int requiredHeight) {
// Raw height and width of the image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > requiredHeight || width > requiredWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the required height and width
while ((halfHeight / inSampleSize) >= requiredHeight
&& (halfWidth / inSampleSize) >= requiredWidth){
inSampleSize *= 2;
}
}
return inSampleSize;
}
From activity_editor.xml:
<ImageButton
android:id="#+id/picture"
android:layout_height="72dp"
android:layout_width="72dp"
android:src="#drawable/ic_photo"
android:layout_gravity="center" />
Link to the repository here.
I am getting pretty frustrated with all these official Android docs that conveniently gloss over the fact that even when you apply a Bitmap to an ImageView, the ImageView's dimensions are 0, 0, and yet you can't get the dimensions prior to mapping, either!
https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
All these methods assume you already know fixed dimensions for the ImageView's height and width in terms of pixels, but this is almost useless because in practice you're supposed to either use dp units or layout_weight so things scale to the viewable region so things look right on various phones.
The only way, it would seem, to get the dimensions is to go to the trouble of inefficiently mapping the bitmap and then getting the dimensions that way, but even if you do, the dimensions will show up as 0 if you do imageView.getWidth() or getHeight()! You have to do a bunch of weird async stuff to wait until the dimensions somehow "settle" and THEN you can finally get the dimensions, but at this stage, what's the point when you've already wasted time doing an inefficient mapping?
Is there some well known workaround to all this that Google isn't explaining in the docs? How are you supposed to know the ImageView dimensions when you're not working with pixels in the XML? It's mind-boggling to me that this isn't documented more.
Here is a sample of the problem:
<ImageView
android:id="#+id/my_imageview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
I have this ImageView inside a DialogFragment. The idea is that I can map a Bitmap to this ImageView and it will fit inside the DialogFragment by means of something like myImageView.setImageBitmap(BitmapFactory.decodeFile(path_to_file));, but this by itself is inefficient if the Bitmap is large.
However, in order to load the Bitmap efficiently, you need to already know the dimensions of the ImageView -- and in pixels! But you can't get the dimensions of the ImageView until you've already mapped the Bitmap inefficiently and waited for some kind of post-execute stage where the dimensions have settled in.
These are the methods I am using to do efficient mapping (assuming you already know the sizes -- it breaks if one of the dimensions is 0, so I added a fix). This code is from Google:
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height == 0 || width == 0) {
return 0; //my fix
}
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromFilePath(String pathName, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(pathName, options);
}
And for example this does not work:
myImageView.post(new Runnable() {
#Override
public void run() {
int reqHeight = myImageView.getHeight(); //height = 0
int reqWidth = myImageView.getWidth(); //width = 528
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(picFullPath, options);
int realWidth = options.outWidth;
int realHeight = options.outHeight;
reqHeight = realHeight * reqWidth / realWidth; //reqHeight = 396, reqWidth = 528
Bitmap bm = decodeSampledBitmapFromFilePath(picFullPath, reqWidth, reqHeight);
myImageView.setImageBitmap(bm);
}
});
myImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int finalHeight = myImageView.getHeight(); //480!
int finalWidth = myImageView.getWidth(); //608!
}
});
You Should get height and Width of view after inflate any view from XML or Dynamically and then use bellow code to get rendered view height and width :
imageView.measure(0,0);
imageView.getMeasuredHeight();
imageView.getMeasuredWidth();
But Above method may given 0 for height and width , if you are not passing any height and width from XML or you are not used any relative property in Relative layout
I use this approach when I need to load bitmap after I know ImageView size:
myImageView.post(new Runnable() {
#Override
public void run() {
int requiredHeight = myImageView.getHeight(); //height is ready, but is 0 - not calculated.
int requiredWidth = myImageView.getWidth(); //width ready
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
int realWidth = option.outWidth;
int realHeight = option.outHeight;
//calculating required Height
requiredHeight = realHeight / realWidth * requiredWidth;
//now we have both - required height and width.
Bitmap bm = decodeSampledBitmapFromFilePath(pathName, requiredWidth, requiredHeight);
myImageView.setImageBitmap(bm);
}
});
This question already has an answer here:
Bitmap too large to be uploaded into a texture
(1 answer)
Closed 7 years ago.
In my android app, have all the images in the drawable folder. On most phones, we had no issue. But some phones have out of memory error. When the images copying for example to the drawable-xhdpi folder the issue is gone. What is the reason this problem, how can i fix it?
drawable is equivalent of drawable-mdpi
If you put your images in that folder they will get up-sampled for higher resolutions devices and that up-sampling can trigger OOM if images are large.
If you put same sized images in drawable-xhdpi you will have upsampled images only on larger xxhdpi devices, and downsampled on others.
If you want to avoid automatic up/down sampling of images put them in drawable-nodpi folder.
Different devices might have different size limits. Try using: drawable-xxhdpi
Helpful cheat sheet: http://i.stack.imgur.com/kV4Oh.png
For managing Out Of Memory Error one thing you may need to do is reduce the image size by compressing it and keep it in drawable folders.which is useful to reduce the app size and also memory consumption at runtime.
Or you may need to use the following class for reducing the image size aspect ratio.
ImageResizer
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight, boolean isLow) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
if (isLow) {
options.inPreferredConfig = Bitmap.Config.RGB_565;
}
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
/**
* Calculate an inSampleSize for use in a {#link BitmapFactory.Options} object when decoding
* bitmaps using the decode* methods from {#link BitmapFactory}. This implementation calculates
* the closest inSampleSize that is a power of 2 and will result in the final decoded bitmap
* having a width and height equal to or larger than the requested width and height.
*
* #param options An options object with out* params already populated (run through a decode*
* method with inJustDecodeBounds==true
* #param reqWidth The requested width of the resulting bitmap
* #param reqHeight The requested height of the resulting bitmap
* #return The value to be used for inSampleSize
*/
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// BEGIN_INCLUDE (calculate_sample_size)
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
// This offers some additional logic in case the image has a strange
// aspect ratio. For example, a panorama may have a much larger
// width than height. In these cases the total pixels might still
// end up being too large to fit comfortably in memory, so we should
// be more aggressive with sample down the image (=larger inSampleSize).
long totalPixels = width * height / inSampleSize;
// Anything more than 2x the requested pixels we'll sample down further
final long totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels > totalReqPixelsCap) {
inSampleSize *= 2;
totalPixels /= 2;
}
}
return inSampleSize;
// END_INCLUDE (calculate_sample_size)
}
Usage
private Bitmap mBackground;
private Drawable mBackgroundDrawable;
#Override
protected void onCreate(Bundle savedInstanceState) {
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.parent);
final Resources res = getResources();
int[] dimensions = Util.getDisplayDimensions(this);
mBackground = ImageResizer.decodeSampledBitmapFromResource(res, R.drawable.bg, 100, 100, false);
mBackgroundDrawable = new BitmapDrawable(res, mBackground);
linearLayout.setBackground(mBackgroundDrawable);
}
#Override
protected void onDestroy() {
recycle();
super.onDestroy();
}
private void recycle() {
if (mBackground != null) {
mBackground.recycle();
mBackground = null;
if (mBackgroundDrawable != null)
mBackgroundDrawable = null;
}
}
Note : If your applying true as third argument which help you to reduce the image size effectively using Bitmap.Config.RGB_565.
if (isLow) {
options.inPreferredConfig = Bitmap.Config.RGB_565;
}
Finally, research about OOM.
I am using camera API to take picture i have to open camera in different sizes according to my Image view size. I am following the sample project which we get inside Android sdk/sample/adroid-18 at the name "ApiDemo" the thing i have changed is not set camera on setcontentview. I have set the camera on Frame Layout. at first my camera preview was starched so i got the camera OptimalPreviewSize and make FrameLayout parameter width and height as wrap-content.Now the camera preview is smaller then ImageView (The size i want). If i make the size of FrameLayout parameter as match-parent then camera View is stretch.How to resolve this issue.
find this link for more specification. Android camera preview look strange
UPDATE
My camera preview size is fine now i use the on Layout method the idea was i have the bigger layout then my ImageView and now camera preview is looking good.
Now the Problem I am facing is set the image of proper size for this I have to center crop and scale in same size in like my ImageView.this Image i get by TakePicture method and saved in sdcard.
For this I am using this method:-
public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) {
int sourceWidth = source.getWidth();
int sourceHeight = source.getHeight();
// Compute the scaling factors to fit the new height and width, respectively.
// To cover the final image, the final scaling will be the bigger
// of these two.
float xScale = (float) newWidth / sourceWidth;
float yScale = (float) newHeight / sourceHeight;
float scale = Math.max(xScale, yScale);
// Now get the size of the source bitmap when scaled
float scaledWidth = scale * sourceWidth;
float scaledHeight = scale * sourceHeight;
// Let's find out the upper left coordinates if the scaled bitmap
// should be centered in the new size give by the parameters
float left = (newWidth - scaledWidth) / 2;
float top = (newHeight - scaledHeight) / 2;
// The target rectangle for the new, scaled version of the source bitmap will now
// be
RectF targetRect = new RectF(left+50, top, left + scaledWidth, top + scaledHeight+50);
// RectF targetRect = new RectF(0, 0, newWidth, newHeight/2);
// Finally, we create a new bitmap of the specified size and draw our new,
// scaled bitmap onto it.
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
Canvas canvas = new Canvas(dest);
canvas.drawBitmap(source, null, targetRect, null);
return dest;
}
But the result image quality is not good.Height Corners are cutting from top and bottom, and result image quality is not good.Pixels are stretching.
Don't tell me to use scaleType=Center_crop i can't use it in my case,and don't want to show cropping frame to user,this all process should not show on UI.
UPDATE
I used blow method for crop image from center and scale according to my imageView size
Bitmap dstBmp = ThumbnailUtils.extractThumbnail(source, newWidth, newHeight);
But the bitmap i got is not looking same the camera preview shown on FrameLayout. because camera preview is big.I think these code cropped the large area.
I tried to reduce the width and change the height but not getting the same cropped image in which ratio i want.
One more idea i have after picture crop a last image frame set automatically on FrameLayout. can we get that set frame from Frame Layout. How is this possible?
Here is question like this How to retrieve the visible part of a SurfaceView in Android do any one have solution.
I want to achieve this by this line ThumbnailUtils.extractThumbnail(source, newWidth, newHeight);and by this line i am getting src like image described in diagram .
What to change in this line exactly ????
Center crop an image may be help you this.
public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) {
int sourceWidth = source.getWidth();
int sourceHeight = source.getHeight();
// Compute the scaling factors to fit the new height and width, respectively.
// To cover the final image, the final scaling will be the bigger
// of these two.
float xScale = (float) newWidth / sourceWidth;
float yScale = (float) newHeight / sourceHeight;
float scale = Math.max(xScale, yScale);
// Now get the size of the source bitmap when scaled
float scaledWidth = scale * sourceWidth;
float scaledHeight = scale * sourceHeight;
// Let's find out the upper left coordinates if the scaled bitmap
// should be centered in the new size give by the parameters
float left = (newWidth - scaledWidth) / 2;
float top = (newHeight - scaledHeight) / 2;
// The target rectangle for the new, scaled version of the source bitmap will now
// be
RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);
// Finally, we create a new bitmap of the specified size and draw our new,
// scaled bitmap onto it.
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
Canvas canvas = new Canvas(dest);
canvas.drawBitmap(source, null, targetRect, null);
return dest;
}
#Akanksha Please use this below code, you just need to pass the path of the saved image, and the hight and width of our imageview. This code works perfectly for me.
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class ImageHandler {
/**
* Decode and sample down a bitmap from a file to the requested width and
* height.
*
* #param filename
* The full path of the file to decode
* #param reqWidth
* The requested width of the resulting bitmap
* #param reqHeight
* The requested height of the resulting bitmap
* #return A bitmap sampled down from the original with the same aspect
* ratio and dimensions that are equal to or greater than the
* requested width and height
*/
public static Bitmap decodeSampledBitmapFromFile(String filename,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filename, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
// This offers some additional logic in case the image has a
// strange
// aspect ratio. For example, a panorama may have a much larger
// width than height. In these cases the total pixels might
// still
// end up being too large to fit comfortably in memory, so we
// should
// be more aggressive with sample down the image (=larger
// inSampleSize).
final float totalPixels = width * height;
// Anything more than 2x the requested pixels we'll sample down
// further.
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
}
return inSampleSize;
}
}
I call this method inside async task because it may take too much UImemory and time
Here is how I call it.
class Asyncing extends AsyncTask {
private int reqWidth;
private int reqHeight;
private ImageView iv;
private String fileName;
private ProgressDialog pd;
public Asyncing(int reqWidth, int reqHeight, ImageView iv,
String fileName) {
super();
this.reqWidth = reqWidth;
this.reqHeight = reqHeight;
this.fileName = fileName;
this.iv = iv;
}
#Override
protected Bitmap doInBackground(String... params) {
return ImageHandler.decodeSampledBitmapFromFile(params[0],
reqWidth, reqHeight);
}
#Override
protected void onPostExecute(Bitmap result) {
iv.setImageBitmap(result);
if (pd.isShowing()) {
pd.setMessage(getString(R.string.completed));
pd.dismiss();
}
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPreExecute() {
pd = ProgressDialog.show(CustomerDetailsActivity.this, "",
getString(R.string.processing_signature));
super.onPreExecute();
}
}
This is how you need to call the asynctask
signedImagePath = data.getExtras().getString("imagePath");
new Asyncing(signature_img.getWidth(), signature_img.getHeight(),
signature_img, "spenTest.png").execute(signedImagePath);
above code is written according to my requirements,you modify it according to yours.