使用Bitmap.createBitmap遇到的问题

简介: 使用Bitmap.createBitmap遇到的问题

Bitmap.java中createBitmap函数调用的是以下重构方法

public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
            Matrix m, boolean filter) {
        checkXYSign(x, y);
        checkWidthHeight(width, height);
        if (x + width > source.getWidth()) {
            throw new IllegalArgumentException("x + width must be <= bitmap.width()");
        }
        if (y + height > source.getHeight()) {
            throw new IllegalArgumentException("y + height must be <= bitmap.height()");
        }
        // check if we can just return our argument unchanged
        if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&
                height == source.getHeight() && (m == null || m.isIdentity())) {
            return source;
        }
        int neww = width;
        int newh = height;
        Canvas canvas = new Canvas();
        Bitmap bitmap;
        Paint paint;
        Rect srcR = new Rect(x, y, x + width, y + height);
        RectF dstR = new RectF(0, 0, width, height);
        Config newConfig = Config.ARGB_8888;
        final Config config = source.getConfig();
        // GIF files generate null configs, assume ARGB_8888
        if (config != null) {
            switch (config) {
                case RGB_565:
                    newConfig = Config.RGB_565;
                    break;
                case ALPHA_8:
                    newConfig = Config.ALPHA_8;
                    break;
                //noinspection deprecation
                case ARGB_4444:
                case ARGB_8888:
                default:
                    newConfig = Config.ARGB_8888;
                    break;
            }
        }
        if (m == null || m.isIdentity()) {
            bitmap = createBitmap(neww, newh, newConfig, source.hasAlpha());
            paint = null;   // not needed
        } else {
            final boolean transformed = !m.rectStaysRect();
            RectF deviceR = new RectF();
            m.mapRect(deviceR, dstR);
            neww = Math.round(deviceR.width());
            newh = Math.round(deviceR.height());
            bitmap = createBitmap(neww, newh, transformed ? Config.ARGB_8888 : newConfig,
                    transformed || source.hasAlpha());
            canvas.translate(-deviceR.left, -deviceR.top);
            canvas.concat(m);
            paint = new Paint();
            paint.setFilterBitmap(filter);
            if (transformed) {
                paint.setAntiAlias(true);
            }
        }
        // The new bitmap was created from a known bitmap source so assume that
        // they use the same density
        bitmap.mDensity = source.mDensity;
        canvas.setBitmap(bitmap);
        canvas.drawBitmap(source, srcR, dstR, paint);
        canvas.setBitmap(null);
        return bitmap;
    }

注意发现其中有以下代码

 // check if we can just return our argument unchanged
 if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&
    height == source.getHeight() && (m == null || m.isIdentity())) {
    return source;
 }

以上代码的逻辑是:如果源位图是 immutable且请求返回的位图是和源位图一样的,则直接返回源位图,并不创建新位图。

所以你在使用它的时候很可能会返回一个你之前传进来的bitmap。所以如果你把认为是临时变量的bitmap回收掉之后,其实是把不该回收的也回收了。这时就会抛出诡异的bitmap回收问题,说是使用了recycled的bitmap。如果一定需要创建一个拷贝的话,可以尝试使用Bitmap.copy(Config config, boolean isMutable)方法代替。


目录
相关文章
|
22天前
|
存储 Java
Bitmap位图(Java实现)
本文介绍了使用Java实现一个简单的Bitmap,通过自定义byte数组存储数据,提供put和exist方法分别用于插入数据和查询数据是否存在。Bitmap利用位操作高效地管理大量布尔值,适用于空间优化的场景。代码中详细解释了位图的核心原理、方法实现及边界检查。后续计划探讨位图在海量数据去重中的应用及JDK BitSet源码分析。
55 7
|
2月前
|
存储 监控
Bitmap
【10月更文挑战第7天】
35 1
|
6月前
|
存储 算法 Java
BitMap介绍
BitMap介绍
35 0
|
6月前
|
开发框架 .NET C#
详细解读Bitmap的优化
详细解读Bitmap的优化
41 0
|
6月前
|
API Android开发
55. 【Android教程】位图:Bitmap
55. 【Android教程】位图:Bitmap
77 0
|
Java Android开发
Bitmap详解
Bitmap的分析与使用 Bitmap的创建 创建Bitmap的时候,Java不提供new Bitmap()的形式去创建,而是通过BitmapFactory中的静态方法去创建,如:BitmapFactory.
2107 0
|
存储 编解码 API
|
存储 算法 程序员
Bitmap 算法
位图算法,内存中连续的二进制位bit,用于对大量整型数据做去重和查询。 举个例子,给定一块长度是10bit的内存空间,依次插入4,3,2,1,怎么存储? 1. 给定长度是10的bitmap,每一个bit位分别对应着从0到9的10个整型数。
1537 0