java.lang.IllegalStateException: 无法获取像素,因为Config#HARDWARE格式的位图不支持像素访问。

9

我正在使用Palette从位图中获取vibrantSwatch颜色。

在编写此代码之前,我要从uri获取位图(在API 29中getBitmap已过时):

Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(),
    Uri.fromFile(ImageModelArrayList.get(position).getImageUri()));

由于被弃用了,现在我编写了这段代码来获取位图:
 ImageDecoder.Source source = ImageDecoder.createSource(context.getContentResolver(),
                    Uri.fromFile(ImageModelArrayList.get(position).getImageUri()));
            Bitmap bitmap = ImageDecoder.decodeBitmap(source);

现在在这个调色板代码中,如果我使用getBitmap没有问题,但是如果我使用ImageDecoder则会崩溃:

Palette p = createPaletteSync(bitmap);
            Palette.Swatch vibrantSwatch = p.getDominantSwatch();
            Log.d(TAG, "onBindViewHolder: vibrantSwatch " + vibrantSwatch);
            if (vibrantSwatch != null) {
                holder.constraintLayout.setBackgroundColor(vibrantSwatch.getRgb());
            }

错误:
2020-02-29 12:32:56.722 9865-9865/com.msp.project E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.msp.project, PID: 9865
java.lang.IllegalStateException: unable to getPixels(), pixel access is not supported on Config#HARDWARE bitmaps
    at android.graphics.Bitmap.checkHardware(Bitmap.java:401)
    at android.graphics.Bitmap.getPixels(Bitmap.java:1760)

我也遇到了同样的问题,你找到解决方案了吗? - nullVoid
4个回答

15

您可以将位图复制到一个可变的位图中,虽然不是最理想的方法,但它是可行的:

ImageDecoder.decodeBitmap(source).copy(Bitmap.Config.RGBA_F16, true)

不确定这是否是最佳解决方案,但它起作用了! - htafoya
如果您仍在处理异常,请使用以下代码: ImageDecoder.decodeBitmap(ImageDecoder.createSource(mContext.getContentResolver(),selectedImage)).copy(Bitmap.Config.ARGB_8888, true); - мalay мeнтa

9

在Compose和Coil中:

import coil.compose.rememberImagePainter

val imagePainter = rememberImagePainter(
                    data = product.imageUrl,
                    builder = {
                        crossfade(true)
                        placeholder(R.drawable.ic_placeholder)
                        allowHardware(false) //IMPORTANT!
                    }
                )

allowHardware(false) 成功了!! - codingmonk21

7

ImageDecoder.decodeBitmap()默认返回不可变位图。像素内存的默认分配是HARDWARE,但在存在小图像或HARDWARE不兼容的情况下可能会切换到software。(更多信息

要获取可变位图,您可以设置isMutableRequired = true。但当分配为HARDWARE时,位图是不可变的,因此首先需要更改解码器的分配。

您可以使用其他带有OnHeaderDecodedListenerdecodeBitmap()重载来处理此问题。

var mutableBitmap = ImageDecoder.decodeBitmap(
                    source,
                    ImageDecoder.OnHeaderDecodedListener { decoder, info, source ->
                        decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE
                        decoder.isMutableRequired = true
                    })

1

替换

ImageDecoder.decodeBitmap(source)

通过

ImageDecoder.decodeBitmap(source, (imageDecoder, imageInfo, source1) -> imageDecoder.setMutableRequired(true));

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