首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jetpack编写不可变的ImageBitmap以传递给Canvas

Jetpack编写不可变的ImageBitmap以传递给Canvas
EN

Stack Overflow用户
提问于 2021-01-10 15:09:58
回答 1查看 2.5K关注 0票数 2

将不可变图像加载到画布时会崩溃,并显示

代码语言:javascript
复制
java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor

在经典的Android Canvas和Compose Canvas中。

使用下面的代码片段是导致Jetpack Compose崩溃的原因。

代码语言:javascript
复制
val deferredResource: DeferredResource<ImageBitmap> =
    loadImageResource(id = R.drawable.landscape2)

deferredResource.resource.resource?.let { imageBitmap ->
    val paint = Paint().apply {
        style = PaintingStyle.Stroke
        strokeWidth = 1f
        color = Color(0xffFFEE58)

    }
    Canvas(image = imageBitmap).drawRect(0f, 0f, 100f, 100f, paint)
}

这是使用位图解决的,可以使用here

代码语言:javascript
复制
Bitmap workingBitmap = Bitmap.createBitmap(chosenFrame);
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);

我可以使用以下命令将ImageBitmap转换为安卓Bitmap

代码语言:javascript
复制
        val bitmap = imageBitmap.asAndroidBitmap().copy(Bitmap.Config.ARGB_8888, true)

我发现还可以使用以下命令将Bitmap转换回ImageBitmap

代码语言:javascript
复制
 val newImageBitmap = bitmap.asImageBitmap()

因此,在使用下面的代码片段在该位图上绘制后得到的结果是

代码语言:javascript
复制
  val canvas = Canvas(newImageBitmap)

    canvas.drawRect(0f, 0f, 200f, 200f, paint = paint)
    canvas.drawCircle(
        Offset(
            newImageBitmap.width / 2 - 75f,
            newImageBitmap.height / 2 + 75f
        ), 150.0f, paint
    )

    Image(bitmap = newImageBitmap)

有没有一种不那么复杂的方法,不用在位图和ImageBitmap之间来回转换,就可以用Canvas在ImageBitmap上绘图?

EN

回答 1

Stack Overflow用户

发布于 2021-01-10 21:31:35

loadImageResource()使用带有Bitmap.decodeResource(resources, drawableId)AndroidImageBitmap实现,它请求在不带选项的情况下调用它。

这可能是作曲的局限性。您可能需要编写自己的loadingImageResource(),它将使用可变Bitmap调用您自己的ImageBitmap实现。

代码语言:javascript
复制
fun imageFromResource(res: Resources, resId: Int): ImageBitmap {
    return MutableAndroidImageBitmap(BitmapFactory.decodeResource(res, resId, BitmapFactory.Options().apply { inMutable = true }))
}
代码语言:javascript
复制
class MutableAndroidImageBitmap(internal val bitmap: Bitmap) : ImageBitmap 

请注意,由于在将ImageBitmap绘制到基础Canvas时,conversion asAndroidBitmap()会检查ImageBitmap的实现,因此拖放ImageBitmap将失败。

我想你应该坚持你在问题中陈述的步骤。asImageBitmap()不会将ImageBitmap转换为Bitmap,它只是返回包装的内部属性。将Bitmap转换为ImageBitmap会读取像素数据并创建其副本。

代码语言:javascript
复制
suspend fun ImageBitmap.mutate(context: CoroutineContext = EmptyCoroutineContext, config: Bitmap.Config) = withContext(context) {
    val workingBitmap = asAndroidBitmap() //this is just access to `bitmap` property
    val mutableBitmap = workingBitmap.copy(config, true)
    workingBitmap.recycle()
    mutableBitmap.asImageBitmap()
}

已打开问题跟踪器https://issuetracker.google.com/issues/177129056上的错误

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65650887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档