【问题标题】:Android: modify and save Bitmap, how to avoid OOM?Android:修改保存Bitmap,如何避免OOM?
【发布时间】:2016-01-23 21:33:21
【问题描述】:

在我的项目中,我需要操作位图并保存它。

为了操纵图像,我应用了一个矩阵,如下所示:

Bitmap b = Bitmap.createBitmap(((BitmapDrawable) imageView.getDrawable()).getBitmap(), 0, 0,width, height, matrix, true);

我这样保存它:

b.compress(Bitmap.CompressFormat.JPEG, 100, out);

问题是,如果这样做,如果位图很大,我会得到 OOM 错误。

有什么建议可以避免吗?

不幸的是,缩小位图不是一个可接受的解决方案,因为我需要保持位图质量。

【问题讨论】:

    标签: android bitmap


    【解决方案1】:

    我也有很多带有位图的 OOM,尤其是在较旧的(三星)设备上。您可以使用的一种简单方法是捕获 OOM,启动 GC,然后重试。如果再次失败,您可以(例如)向用户显示错误消息。

    private void compressBitmap(/* args */) {
        Bitmap b = Bitmap.createBitmap(((BitmapDrawable) imageView.getDrawable()).getBitmap(), 0, 0,width, height, matrix, true);
        b.compress(Bitmap.CompressFormat.JPEG, 100, out);
    }
    
    try {
        compressBitmap(/* args */);
    } catch(OutOfMemoryError e) {
        System.gc();
        // try again
        try {
            compressBitmap(/* args */);
        } catch(OutOfMemoryError e) {
            System.gc();
            // Inform user about the error. It's better than the app crashing
        }
    }
    

    但这只是一种解决方法。如果你真的想在这种情况下有效防止OOM,我认为你必须使用NDK。无论如何,总比应用崩溃要好。

    【讨论】:

    • 本地化的好建议
    • 要点是:即使是原生,怎么可能防止OOM?在任何情况下,我们都需要将位图加载到内存中,不是吗?如果我们将位图加载到内存中,即使使用本机方法,我们也会得到 OOM,不是吗?
    • 我不是原生的专家,但据我所知,使用 NDK 分配内存不计入 Java 堆,see question/answers here。因此,如果您在那里加载和操作您的位图,它不会导致任何 OOM。
    猜你喜欢
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 2011-09-26
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多