Search code examples
javaandroidbitmapbitmapfactory

Why Bitmap.createBitmap() returns mutable Bitmap that differs from source bitmap?


According documentation Bitmap createBitmap (Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) method :

Returns an immutable bitmap from subset of the source bitmap, transformed by the optional matrix. The new bitmap may be the same object as source, or a copy may have been made. It is initialized with the same density as the original bitmap. If the source bitmap is immutable and the requested subset is the same as the source bitmap itself, then the source bitmap is returned and no new bitmap is created.

I've got a method that applies orientation to existed bitmap:

private Bitmap getOrientedPhoto(Bitmap bitmap, int orientation) {
        int rotate = 0;
        switch (orientation) {
            case ORIENTATION_ROTATE_270:
                rotate = 270;
                break;
            case ORIENTATION_ROTATE_180:
                rotate = 180;
                break;
            case ORIENTATION_ROTATE_90:
                rotate = 90;
                break;
            default:
                return bitmap;
        }

        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Matrix mtx = new Matrix();
        mtx.postRotate(rotate);
        return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
    }

I'm calling it from here:

Bitmap tmpPhoto = BitmapFactory.decodeFile(inputPhotoFile.getAbsolutePath(), tmpOpts);
Bitmap orientedPhoto = getOrientedPhoto(tmpPhoto, orientation);

I've checked that tmpPhoto is immutable but getOrientedPhoto() still returns mutable image which is copy of tmpPhoto. Does anyone knows how to use Bitmap.createBitmap() without creating new bitmap object and what's wrong with my code?


Solution

  • Seems like it's really just unclear documentation for this method. I've found this code in Bitmap crateBitmap() method:

    // 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;
    }
    

    This means that source bitmap are returning back only in case if it's immutable and no transformations required.