Java / Android - 创建Bitmap - OOM错误

时间:2017-05-15 13:13:54

标签: java android bitmap out-of-memory

Edit2:我添加了android:largeHeap =" true"到清单,现在它似乎工作正常。但我现在不会关闭它,因为我不确定它是否是正确的方法,而且我会做更多的测试。

我正在使用集成相机的应用程序(camera1,应用程序需要在Android 4.4.2上运行),应用程序能够以横向模式拍摄照片,现在我想添加可能性以纵向模式拍摄风景照片。

所以我基本上拍摄了一个肖像模式照片,旋转并裁剪它(从顶部和底部切掉,因此它的比例为4:3)。

此代码适用于Android 6.0.1(Samsung Galaxy Tab S2)(目前正在测试但已有30个),但我在4.4.2(Motorola Symbol TC70)上收到OOM错误。拍摄第3张照片后,我收到错误。

System.out.println("Character Segmentation the image at " + path + "... ");
// get the jpeg image from the internal resource folder
Mat image = MatImageFromPath;           

// convert the image in gray scale
Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2GRAY);
// thresholding the image to make a binary image
Imgproc.threshold(image, image, 100, 255, Imgproc.THRESH_BINARY_INV);

// finding the contours
ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
Imgproc.findContours(image, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

Imgproc.drawContours(image, contours, 3, new Scalar(0, 255, 0),3);

// finding best bounding rectangle for a contour whose distance is closer to the image center that other ones
Rect rect = new Rect();
ArrayList<Rect> contourRects = new ArrayList<Rect>();
Point p1 = new Point(rect.x,rect.y);
Point p2 = new Point((rect.x+rect.width),(rect.y+rect.height));
int i=0;
    for (MatOfPoint contour : contours) {
        rect = Imgproc.boundingRect(contour);
        contourRects.add(rect);
        contour2f = new MatOfPoint2f( contours.get(i).toArray() );
        i++;
        }

        Collections.sort(contourRects, new Comparator<Rect>(){
        @Override
        public int compare(Rect o1, Rect o2){
        return o1.x-o2.x;
        }
        });

        for (int j = 0; j <= contourRects.size()-1; j++) {
            if ((contourRects.get(j).width >= 50 && contourRects.get(j).width <= 120) && 
                                (contourRects.get(j).height >= 150 && contourRects.get(j).height <= 210)) {
                            System.out.println(contourRects.get(j).width);
                            Mat result = image.submat(contourRects.get(j));
                            Imgcodecs.imwrite("BoundingBox/"+(j+1)+".png", result);
//                           write the new image on disk
                            path = "BoundingBox/"+(j+1)+".png";
                        } else {
                            continue;
                        }
                    }
                    Imgcodecs.imwrite("BoundingBox/draw.png", image);
                    label2.setIcon(ImageFromPath(path));

我添加了这段代码:

java.lang.OutOfMemoryError
    at android.graphics.Bitmap.nativeCreate(Native Method)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:809)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:786)
    at android.graphics.Bitmap.createBitmap(Bitmap.java:718)
    at de.sdnord.ballistiks.topspeedgt.main.detail_fragment.fotos.CameraActivity$1.onPictureTaken(CameraActivity.java:66)
    at android.hardware.Camera$EventHandler.handleMessage(Camera.java:940)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5050)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
    at dalvik.system.NativeStart.main(Native Method)

这是第66行:

if (PreferenceManager.getDefaultSharedPreferences(CameraActivity.this).getString(Constants.FOTO_ORIENTATION, Constants.FOTO_ORIENTATION_LANDSCAPE).equals(Constants.FOTO_ORIENTATION_PORTRAIT)) {
            Matrix matrix = new Matrix();
            matrix.postRotate(90);

            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            bitmap = Bitmap.createBitmap(bitmap, bitmap.getWidth()/2 - bitmap.getHeight()*heightMultiplier/widthMultiplier/2, 0, bitmap.getHeight()*heightMultiplier/widthMultiplier, bitmap.getHeight(), matrix, false);
            ByteArrayOutputStream streamsy = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, streamsy);
            data = streamsy.toByteArray();
            bitmap.recycle();
            try {
                streamsy.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

我有点无能为力,希望有人可以提供帮助,有想法或提示。

敬畏

编辑: 我正在裁剪它,因为我只想要屏幕的中间部分。 Camera Screenshot

Edit2:我添加了android:largeHeap =&#34; true&#34;到清单,现在它似乎工作正常。但我现在不会关闭它,因为我不确定它是否是正确的方法,而且我会做更多的测试。

1 个答案:

答案 0 :(得分:0)

我添加了android:largeHeap =&#34; true&#34;到清单,现在它工作正常。

敬畏