java.lang.IllegalStateException: 无法 getPixels(),Config#HARDWARE 位图不支持像素访问

Dny*_*war 8 android bitmap palette

我正在使用 Palette 从位图中获取鲜艳的Swatch 颜色。

在编写此代码之前从 uri 获取位图(在 API 29 中,getBitmap 已弃用):

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

由于 deprication 我现在写了这段代码来获取位图:

 ImageDecoder.Source source = ImageDecoder.createSource(context.getContentResolver(),
                    Uri.fromFile(ImageModelArrayList.get(position).getImageUri()));
            Bitmap bitmap = ImageDecoder.decodeBitmap(source);
Run Code Online (Sandbox Code Playgroud)

现在在这个 Palette 代码中,我崩溃了(如果我使用 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());
            }
Run Code Online (Sandbox Code Playgroud)

错误:

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)
Run Code Online (Sandbox Code Playgroud)

Dr.*_*cky 11

在撰写和线圈中:

import coil.compose.rememberImagePainter

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


Beu*_*euz 9

您可以将位图复制到可变位图,虽然不理想,但它有效:

ImageDecoder.decodeBitmap(source).copy(Bitmap.Config.RGBA_F16, true)
Run Code Online (Sandbox Code Playgroud)


小智 8

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

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

您可以使用其他decodeBitmap()重载来处理此问题OnHeaderDecodedListener

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