如何使用ImageDecoder获取可变位图?

3
我将按照以下方式创建位图:
       ImageDecoder.Source source = ImageDecoder.createSource(this.getContentResolver(), mSourceUri);
        try {
            bitmap = ImageDecoder.decodeBitmap(source));
        } catch (IOException e) {
            e.printStackTrace();
        }

这返回不可变位图。我看到了Google文档,里面有一个setMutableRequired()方法,但我找不到如何使用该方法的信息。它既无法在ImageDecoder上运行,也无法在源代码上运行。

4个回答

4
ImageDecoder.OnHeaderDecodedListener 作为第二个参数传递给 ImageDecoder.decodeBitmap() 方法。
在监听器中,您可以获得 ImageDecoder,从而能够进行所需的更改。
ImageDecoder.decodeBitmap(imageSource, (decoder, info, source) -> {
    decoder.setMutableRequired(true);
});

4

从API 28开始

ImageDecoder.Source source = ImageDecoder.createSource(getContentResolver(), imageUri);
            ImageDecoder.OnHeaderDecodedListener listener = new ImageDecoder.OnHeaderDecodedListener() {
                @Override
                public void onHeaderDecoded(@NonNull ImageDecoder decoder, @NonNull ImageDecoder.ImageInfo info, @NonNull ImageDecoder.Source source) {
                    decoder.setMutableRequired(true);
                }
            };
            bitmap = ImageDecoder.decodeBitmap(source, listener);

创建一个仅用于解码位图的监听器,这太疯狂了。 - Humpity
@Humpity为什么?位图在视频内存中,你如何在其他情况下访问它呢? - Alexufo

2
一个更漂亮的解决方案。
imageBitmap = imageBitmap.copy(Bitmap.Config.ARGB_8888, true);

请参考这个答案

(保留HTML标签)

1
这个解决方案并不美观——它复制了位图,使所需的内存瞬间增加了一倍。setMutableRequired 是一种没有额外复制的适当方式。 - Dimezis
@Dimezis 以及如何在不复制的情况下从视频内存中获取它? - Alexufo
@Dimezis 你怎么能在不复制的情况下从视频内存中获取它呢? - undefined
1
@Alexufo 使用setMutableRequired,返回的位图将是软件分配的。https://developer.android.com/reference/android/graphics/ImageDecoder#ALLOCATOR_DEFAULT - Dimezis
1
使用setMutableRequired方法,返回的位图将由软件分配。更多信息请参考:https://developer.android.com/reference/android/graphics/ImageDecoder#ALLOCATOR_DEFAULT - undefined
@dimezis 谢谢!你说得对!!! - Alexufo

0

在得到正式答案之前,有类似困难的人可以使用BitmapFactory方法获取可变位图。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(mSourceUri), null, options);

这个答案的启发。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接