【问题标题】:Android - Saving photo taken from Camera , Out of memoryAndroid - 保存从相机拍摄的照片,内存不足
【发布时间】:2015-11-06 01:32:01
【问题描述】:

我有一个用例,用户拍照并且照片必须保存在 sd 卡上。

我已将相机的方向设置为纵向。

虽然 saving the photo on to SD card 我得到了out of memory。

这是日志 -

java.lang.RuntimeException: An error occured while executing doInBackground()
  at android.os.AsyncTask$3.done(AsyncTask.java:300)
  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
  at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
  at java.util.concurrent.FutureTask.run(FutureTask.java:242)
  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
  at java.lang.Thread.run(Thread.java:841)
Caused by: 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 com.philips.cl.di.haircare.util.AppUtility.changeOrientationAndwriteDataToFile(AppUtility.java:382)
  at com.philips.cl.di.haircare.mirror.MirrorCameraViewFragment$SaveBitMap.doInBackground(MirrorCameraViewFragment.java:389)
  at com.philips.cl.di.haircare.mirror.MirrorCameraViewFragment$SaveBitMap.doInBackground(MirrorCameraViewFragment.java:369)
  at android.os.AsyncTask$2.call(AsyncTask.java:288)
  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
  ... 4 more

这是我用来保存的功能 -

public static boolean changeOrientationAndwriteDataToFile(Context context,
        final File pictureFile, final byte[] data, final int camId)
        throws Exception {

    FileOutputStream fos = null;
    Bitmap realImage = null;
    try {

        fos = new FileOutputStream(pictureFile);
        realImage = BitmapFactory.decodeByteArray(data, 0, data.length);
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(camId, info);
        Matrix matrix = new Matrix();

        int rotation = info.orientation;
        int camfacing = info.facing;

        if (camfacing == 1) {
            matrix.setScale(1, -1);
        }
        if (rotation != 0) {
            matrix.postRotate(rotation);

        } else {
            matrix.postRotate(-90);
        }
        realImage = Bitmap.createBitmap(realImage, 0, 0,
                realImage.getWidth(), realImage.getHeight(), matrix, false);
        MediaScannerConnection.scanFile(context,
                new String[] { pictureFile.getPath() },
                new String[] { "image/jpeg" }, null);

        // 100 means maximum quality
        return realImage.compress(Bitmap.CompressFormat.JPEG, 100, fos);
    } catch (final Exception e) {
        throw e;

    } finally {
        if (realImage != null) {
            realImage.recycle();
        }
        if (fos != null) {
            fos.close();
        }
    }

}

行号 - 382 内存不足。

realImage = Bitmap.createBitmap(realImage, 0, 0,
                realImage.getWidth(), realImage.getHeight(), matrix, false);

请帮助解决这个问题。

谢谢。

【问题讨论】:

  • data (byte[]) 应该在创建图像的第二个版本之前进行垃圾收集,因此它不应该是导致 OutOfMemory 错误的原因。您可以稍后初始化fos,以便在第一个版本的 realImage 符合垃圾收集条件后分配它(我认为 Java 有时会自行优化这些东西,但在这种情况下它太复杂了)。
  • 也许你可以在stackoverflow.com/questions/8552298/…的第一个答案中使用方法2(画布而不是新位图)来解决这个问题
  • 我刚刚使用 Android Studio 分析了内存,一旦创建了位图,堆的大小就会增加大约 18 mb。这很奇怪,对于一个小得多的字节数组,为什么堆会增长 18 mb。
  • 18 MiB 看起来您有一张未压缩的 6 兆像素图片。

标签: android memory-management bitmap out-of-memory heap-memory


【解决方案1】:

我使用BitmapFactory Options 解决了它 这是更新的方法 -

public static boolean changeOrientationAndwriteDataToFile(Context context,
        final File pictureFile, final byte[] data, final int camId, int reqWidth , int reqHeight )
        throws Exception {

    FileOutputStream fos = null;
    Bitmap realImage = null;
    Bitmap transformedImage = null ;
    try {

        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(camId, info);
        int rotation = info.orientation;
        int camfacing = info.facing;

        // Out of memory issue fixx -with the sample size concept

        BitmapFactory.Options options = new BitmapFactory.Options();

        options.inJustDecodeBounds = true ;

        BitmapFactory.decodeByteArray(data, 0, data.length, options);

        options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeight);

        System.out.println("Sample Size : " + options.inSampleSize);

        options.inPreferredConfig = Bitmap.Config.RGB_565;

        options.inJustDecodeBounds = false;

        realImage= BitmapFactory.decodeByteArray(data, 0, data.length, options);

        Matrix matrix = new Matrix();

        if (camfacing == 1) {
            matrix.setScale(1, -1);
        }
        if (rotation != 0) {
            matrix.postRotate(rotation);

        } else {
            matrix.postRotate(-90);
        }
        transformedImage = Bitmap.createBitmap(realImage, 0, 0,
                realImage.getWidth(), realImage.getHeight(), matrix, false);
        MediaScannerConnection.scanFile(context,
                new String[] { pictureFile.getPath() },
                new String[] { "image/jpeg" }, null);

        fos = new FileOutputStream(pictureFile);
        // 100 means maximum quality
        return transformedImage.compress(Bitmap.CompressFormat.JPEG, 100, fos);
    } catch (final Exception e) {
        throw e;

    } finally {
        if (realImage != null) {
            realImage.recycle();
        }
        if(transformedImage !=null)
        {
            transformedImage.recycle();
        }
        if (fos != null) {
            fos.close();
        }
    }

}

这里 - reqWidth 和 reqHeight 是 screen width 和 screen height 因为我必须全屏显示位图。

谢谢。

【讨论】:

    【解决方案2】:

    您可以将android:largeHeap="true" 添加到您的AndroidManifest.xml

    这是一种解决方法。小心使用。

    【讨论】:

      【解决方案3】:

      制作新的位图对象而不是重新创建真实图像

      【讨论】:

      • 如果我创建一个新的位图对象会有什么帮助?请解释一下。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 2021-01-10
      • 2013-04-03
      相关资源
      最近更新 更多