Jetpack Compose中从ImageBitmap提取SVG路径数据的问题
Jetpack Compose签名转SVG路径的精准还原问题
我正在开发Jetpack Compose安卓应用,需要将用户手绘签名转换为SVG <path> 标签可用的格式,精准还原用户绘制内容。
目标
获取能精准还原用户手绘签名的SVG路径数据。
当前问题
现有方案生成的路径数据不准确,无法完整还原签名。比如简单线条会生成大量重复的M/L指令,导入SVG后无法完整显示签名。
当前实现方案
使用Sain包处理用户签名输入,完成后返回ImageBitmap,UI显示正常,但通过自定义extractSVGPath函数解析后得到的路径数据无法准确还原签名。
核心UI代码
var imageBitmap: ImageBitmap? by remember { mutableStateOf(null) } val state = remember { SignatureState() } var isLoading by remember { mutableStateOf(false) } Sain( state = state, modifier = Modifier.fillMaxWidth().height(159.dp), signatureThickness = 2.dp, onComplete = { signatureBitmap -> if (signatureBitmap != null) { imageBitmap = signatureBitmap } else { println("Signature is empty") } }, ) { action -> Row() { Button( onClick = { imageBitmap = null action(SignatureAction.CLEAR) }) { Icon(Icons.Outlined.Delete, contentDescription = "Clear", modifier = Modifier.size(24.dp), tint = Color.Gray) } } Column(modifier = Modifier.fillMaxWidth()) { Row(modifier = Modifier.fillMaxWidth()) { Button(onClick = { isLoading = true coroutineScope.launch { action(SignatureAction.COMPLETE) withContext(Dispatchers.Default) { val pathData = extractSVGPath(imageBitmap!!) // 测试打印返回数据 println(pathData) } withContext(Dispatchers.Main) { isLoading = false } } }, modifier = Modifier.fillMaxWidth(), ) { if (isLoading) { // 显示加载图标 } else { Text(text = "Add Signature") } } } } }
路径解析函数代码
fun extractSVGPath(imageBitmap: ImageBitmap): String { val bmp = imageBitmap.asAndroidBitmap() val width = bmp.width val height = bmp.height var pathData = StringBuilder("M ") var lastX = -1 var lastY = -1 for (y in 0 until height) { for (x in 0 until width) { val pixel = bmp.getPixel(x, y) val alpha = (pixel shr 24) and 0xff if (alpha > 0) { if (lastX == -1 && lastY == -1) { pathData.append("$x $y ") } else { if (abs(x - lastX) > 1 || abs(y - lastY) > 1) { pathData.append("M $x $y ") } else { pathData.append("L $x $y ") } } lastX = x lastY = y } } } return pathData.toString().trim { it <= ' ' } }
正确SVG路径示例
<svg xmlns="http://www.w3.org/2000/svg" width="350" height="150" viewBox="0 0 350 150" fill="none"> <path d="M 150.40625 41.5 L 150.40625 41.5 L 150.40625 42.5 L 150.40625 50.5 L 150.40625 59.5 L 150.40625 63.5 L 149.40625 66.5 L 148.40625 68.5 L 146.40625 69.5 L 145.40625 69.5 L 145.40625 68.5 L 145.40625 68.5 L 149.40625 68.5 L 155.40625 68.5 L 162.40625 68.5" stroke="black" stroke-width="1" fill="none"/> </svg>
寻求解决方案
现寻求以下方向的可行方案:
- 替代的签名输入包(能直接输出SVG路径或原始触摸轨迹数据)
- 更优的ImageBitmap解析方式,生成精准的SVG路径数据
内容的提问来源于stack exchange,提问作者timval
相关产品推荐
相关产品推荐

