简体   繁体   English

拍照并使用图像-内存不足错误

[英]Taking a picture and using the image - Out of memory error

OK, I am developing an android application that takes a photo using the camera, then uses that image in an ImageView. 好的,我正在开发一个Android应用程序,该应用程序使用相机拍摄照片,然后在ImageView中使用该图像。 The problem that I'm having is that I keep getting an java.lang.OutOfMemoryError exception when I try and load the image. 我遇到的问题是,当我尝试加载图像时,总是收到java.lang.OutOfMemoryError异常。

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. 使用我的Samsung SIII,我的图像约为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 我用几种不同的方式重写了此函数,发现有时在调用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! 任何帮助将不胜感激!

OK, I found the answer, thank you sunil! OK,我找到了答案,谢谢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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM