Reputation: 97
OK, I am developing an android application that takes a photo using the camera, then uses that image in an ImageView.
The problem that I'm having is that I keep getting an java.lang.OutOfMemoryError
exception when I try and load the image.
Code to start camera intent:
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
AlertDialog.Builder builder = new AlertDialog.Builder(AddVehicleActivity.this);
builder.setTitle("Select A Method");
builder.setItems(R.array.array_PhotoMethods, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch(which) {
case 0 :
IMAGE_LOCATION = Utility.setFileName(_session); //Returns image path
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(IMAGE_LOCATION)));
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
break;
}
}
});
builder.show();
}
});
From my understanding, this will allow the image to be saved at the full resolution of the camera which I can confirm through the image details in the gallery. Using my Samsung SIII, my image is about 3.3MB. So, I am able to use the camera and store the image I take using the camera to path I specify. The problem comes when trying to use the image.
To load the image, I use the following:
public static Bitmap Shrink(String file, int width, int height) {
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
if (heightRatio > 1 || widthRatio > 1) {
bmpFactoryOptions.inSampleSize = (heightRatio > widthRatio) ? heightRatio : widthRatio;
}
return BitmapFactory.decodeFile(file, bmpFactoryOptions);
}
I have rewritten this functions a few different ways and found out that sometimes, I get the memory error when calling BitmapFactory.decodeFile
My stack trace looks like this:
E/dalvikvm-heap(8355): Out of memory on a 31961104-byte allocation.
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:619)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:385)
at com.autopilot.com.objects.Images.Shrink(Images.java:191)
at com.autopilot.com.adapters.ImageAdapter.getView(ImageAdapter.java:90)
at android.widget.AbsListView.obtainView(AbsListView.java:2437)
at android.widget.GridView.onMeasure(GridView.java:1030)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1396)
at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1038)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:576)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1396)
at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1038)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:576)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.LinearLayout.forceUniformWidth(LinearLayout.java:926)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:906)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
at android.view.View.measure(View.java:15395)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:617)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:399)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:15395)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:833)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2362)
at android.view.View.measure(View.java:15395)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1985)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1226)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1399)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4553)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:525)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4950)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
at dalvik.system.NativeStart.main(Native Method)
From tracing this through, the memory exception occurs anytime that the original bitmap is loaded. I cannot find a way to set the saved image size and when I try to save the bitmap from the intent extras, it's never big enough, usually thumb nail size.
Any help would be greatly appreciated!
Upvotes: 2
Views: 2296
Reputation: 97
OK, I found the answer, thank you sunil!
public static Bitmap Shrink(String file, int width, int height) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, options);
options.inSampleSize = calcSize(options, width, height);
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(file, options);
return bmp;
}
public static int calcSize(BitmapFactory.Options options, int width, int height) {
final int uHeight = options.outHeight;
final int uWidth = options.outWidth;
int inSampleSize = 1;
if (uHeight > height || uWidth > width) {
if (uWidth > uHeight) {
inSampleSize = Math.round((float) uHeight / (float) height);
} else {
inSampleSize = Math.round((float) uWidth / (float) width);
}
}
return inSampleSize;
}
Upvotes: 1