android - 处理多个大位图时出现内存问题

标签 android image bitmap out-of-memory heap-memory

我必须让用户从设备摄像头一张一张地拍摄 10 张图像,然后对每张图像进行灰度缩放处理,最后将它们上传到服务器。

现在在内存小于 1 gb 的低端 android 设备中,我面临一个问题,由于内存/堆问题,页面在从相机应用程序导航回应用程序时再次重新加载,所有 edittext 数据保持设置但已设置imageviews 中的缩略图消失。

步骤:

  1. 捕获多达 10 张图像
  2. 每个灰度级
  3. 检查方向并以正确的方向保存
  4. 显示灰度图像的小缩略图
  5. 第二、三、四步在AsyncTask中完成
  6. 在提交时将所有 10 张图像(从 SD 卡保存的大位图)和其他数据上传到服务器

我引用了以下关于 android 开发人员的教程:

对于图像压缩和缩放:

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

对于图像灰度:

bmpGrayscale = Bitmap.createBitmap(width, height,
                    Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bitmap, 0, 0, paint);

方向处理:

Uri uri = Uri.parse(picPath);
    ExifInterface exif = null;
    try {
        exif = new ExifInterface(uri.getPath());
    } catch (IOException e) {
        e.printStackTrace();
    }

    int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_NORMAL);

    rotationInDegrees = exifToDegrees(rotation);

    private static int exifToDegrees(int exifOrientation) {
        if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
            return 90;
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
            return 180;
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
            return 270;
        }
        return 0;
    }

    public static Bitmap rotate(Bitmap b, int degrees) {
        if (degrees != 0 && b != null) {
            Matrix m = new Matrix();

            m.setRotate(degrees, (float) b.getWidth() / 2,
                    (float) b.getHeight() / 2);
            // m.postRotate(degrees);
            try {
                System.gc();
                Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
                        b.getHeight(), m, true);
                if (b != b2) {
                    b.recycle();
                    b = b2;
                }
            } catch (OutOfMemoryError ex) {
                throw ex;
            }
        }
        return b;
    }

任何人都可以指导我如何压缩或处理内存,以便我执行上述所有步骤并且不会发生上述内存/堆问题。

图像缓存有帮助吗,我试过了,但它对我实现它的方式没有帮助。

提前致谢。

最佳答案

我看到你在做 bimap.recycle - 很好。我发现我必须将每个摄像机图像保存到磁盘,然后从服务或同步任务中按顺序处理每个图像。位图非常占用内存,并且取决于手机上有多少内存,一次只能处理几个。保存到磁盘时,调整 jpg 压缩,以便在读取时消耗更少的内存。

关于android - 处理多个大位图时出现内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22830459/

相关文章:

android - 将位图中特定颜色以外的所有颜色转换为白色

android - 在代码中打开 Gallery of Android 的可靠方法是什么?

asp.net-mvc - Entity Framework /MVC。如何防止在不选择新图像的情况下更新当前记录时删除保存在数据库中的图像 blob

javascript - 在页面加载之前使用 jQuery 定位图像

android - 如何将较小的位图复制到较大的位图中?

java - 提高图片上传质量

java - Eclipse,当输入java代码时,它不会预测任何东西,我喜欢它预测我将要输入的内容

android - 在现有图像上画一个圆圈

android - Activity startActivityForResult 不会触发 onActivityResult

css - 在没有媒体查询的情况下,在表格行交叉的中心页面上锚定图像