You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在桌面端Compose Canvas绘制二维颜色数组像素?

问题描述

我拥有一个编码为二维颜色数组的图像,格式如下:

val pixels = arrayOf(
    arrayOf(color1, color2,... colorN),
    ...
)

我希望在桌面端(非Android)的Compose Canvas上逐像素绘制它:

Canvas(
    modifier = Modifier
        .size(200.dp)
        .background(Color.White)
) {
    drawPixels(pixels) // 需要此类函数
}

目前仅找到drawPoints方法,但它需要为每种颜色准备点列表,当存在数百种不同颜色时,这并非最优方案。请问如何绘制像素数组?

解决方案

性能最优方案:转换为Bitmap后绘制

直接逐像素绘制图形效率极低,推荐将二维颜色数组转换为Skia Bitmap,再通过Compose的drawImage方法绘制,这是大尺寸像素数组的首选方式。

  1. 实现颜色数组转Bitmap的工具函数
import org.jetbrains.skia.Bitmap
import org.jetbrains.skia.ColorAlphaType
import org.jetbrains.skia.ColorType
import org.jetbrains.skia.ImageInfo
import androidx.compose.ui.graphics.Color

fun createBitmapFromPixels(pixels: Array<Array<Color>>): Bitmap {
    val width = pixels.firstOrNull()?.size ?: 0
    val height = pixels.size
    if (width == 0 || height == 0) return Bitmap.makeEmpty()

    return Bitmap().apply {
        allocPixels(ImageInfo.makeS32(width, height, ColorAlphaType.PREMUL))
        for (y in 0 until height) {
            val row = pixels[y]
            for (x in 0 until width) {
                setColor(x, y, row[x].value.toUInt())
            }
        }
    }
}
  1. 在Canvas中绘制Bitmap
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.size
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImage
import androidx.compose.ui.unit.dp

Canvas(
    modifier = Modifier
        .size(200.dp)
        .background(Color.White)
) {
    val bitmap = remember(pixels) { createBitmapFromPixels(pixels) }
    // 绘制Bitmap并适配Canvas尺寸
    drawImage(
        image = bitmap.asImage(),
        dstSize = size.toSize()
    )
}

简单备选方案:逐像素绘制矩形(仅小尺寸场景)

如果像素数组尺寸很小,也可以直接遍历数组绘制单个像素矩形,但性能远低于Bitmap方案:

Canvas(
    modifier = Modifier
        .size(200.dp)
        .background(Color.White)
) {
    val pixelWidth = size.width / (pixels.firstOrNull()?.size ?: 1)
    val pixelHeight = size.height / pixels.size

    pixels.forEachIndexed { y, row ->
        row.forEachIndexed { x, color ->
            drawRect(
                color = color,
                topLeft = Offset(x * pixelWidth, y * pixelHeight),
                size = Size(pixelWidth, pixelHeight)
            )
        }
    }
}

内容的提问来源于stack exchange,提问作者David I. Lipkind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:17:03