Извлечение данных пути из ImageBitmap в Kotlin/Jetpack ComposeAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Извлечение данных пути из ImageBitmap в Kotlin/Jetpack Compose

Сообщение Anonymous »

Я работаю над извлечением данных из нарисованной пользователем подписи в своем приложении Jetpack Compose для Android. Мне нужно преобразовать нарисованную пользователем подпись в формат, который можно использовать в теге
SVG, точно представляющий то, что нарисовал пользователь.
Цель: Получить данные о пути из введенной пользователем подписи, которая точно представляет его рисунок в приложении.
Проблема: Текущее решение предоставляет неточные данные о пути, которые не неточно представляют рисунок пользователя. Ниже приведен пример того, что в настоящее время печатается, когда пользователь завершает рисование подписи:

Код: Выделить всё

M 390 294 L 391 294 L 392 294 L 393 294 L 394 294 L 395 294 L 396 294 L 397 294 L 398 294 L 399 294 L 400 294 L 401 294 M 384 295 L 385 295 L 386 295 L 387 295 L 388 295 L 389 295 L 390 295 L 391 295 L 392 295 L 393 295 L 394 295 L 395 295 L 396 295 L 397 295 L 398 295 L 399 295 L 400 295 L 401 295 M 376 296 L 377 296 L 378 29...
так продолжается долго (даже для простой строки). Когда я помещаю данные в SVG, я иногда вижу часть нарисованного изображения, но никогда все целиком (независимо от установленных мной ширины, высоты и viewBox).
Текущее решение:
Я использую этот пакет для ввода данных пользователем. После того как пользователь завершит свою подпись, пакет возвращает ImageBitmap. Если я отображаю его в пользовательском интерфейсе с помощью компонента Image, он отображается правильно.
Однако, когда я анализирую ImageBitmap с помощью приведенной ниже функции, результирующие данные пути SVG не неточно представляет нарисованную подпись при вставке в реальный SVG.
Вот основной код, обрабатывающий ввод пользователя:

Код: Выделить всё

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!!)
//print the returned data for testing
println(pathData)
}
withContext(Dispatchers.Main) {
isLoading = false
}
}
},
modifier = Modifier.fillMaxWidth(),
) {
if (isLoading) {
//show a loading icon
} 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 
[code]


Я открыт для других решений, будь то другой пакет для рисования подписи, более эффективные способы анализа ImageBitmap или любые другие идеи.
>

Подробнее здесь: https://stackoverflow.com/questions/783 ... ck-compose
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»