Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion classic-components-example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ allprojects {

jvmToolchainVersion = 17

scanbotSdkVersion = "9.0.1"
scanbotSdkVersion = "10.0.0.131-STAGING-SNAPSHOT"

androidCoreKtxVersion = "1.6.0"
constraintLayoutVersion = "2.0.4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ android {

buildTypes {
named("debug") {

minifyEnabled = false
debuggable = true
}
Expand All @@ -41,6 +41,6 @@ kotlin.jvmToolchain(project.ext.jvmToolchainVersion)
dependencies {
implementation(project(":common"))
implementation("io.scanbot:sdk-package-1:${project.ext.scanbotSdkVersion}")
implementation("io.scanbot:sdk-document-enhancer-assets:${project.ext.scanbotSdkVersion}")
implementation("io.scanbot:sdk-document-straightener-assets:${project.ext.scanbotSdkVersion}")
implementation("androidx.appcompat:appcompat:${project.ext.androidxAppcompatVersion}")
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import io.scanbot.sdk.ScanbotSDK
import io.scanbot.sdk.camera.CaptureInfo
import io.scanbot.sdk.document.ui.DocumentScannerView
import io.scanbot.sdk.document.ui.IDocumentScannerViewCallback
import io.scanbot.sdk.documentscanner.DocumentEnhancer
import io.scanbot.sdk.documentscanner.DocumentStraightener
import io.scanbot.sdk.documentscanner.DocumentStraighteningMode
import io.scanbot.sdk.documentscanner.DocumentStraighteningParameters
import io.scanbot.sdk.image.ImageRef
Expand Down Expand Up @@ -50,7 +50,7 @@ class DocumentCameraActivity : AppCompatActivity() {

documentScannerView = findViewById(R.id.document_scanner_view)
resultView = findViewById<View>(R.id.result) as ImageView
val documentEnhancer = scanbotSdk.createDocumentEnhancer()
val documentStraightener = scanbotSdk.createDocumentStraightener()
scanbotSdk.createDocumentScanner().onSuccess { documentScanner ->

documentScannerView.apply {
Expand All @@ -70,8 +70,8 @@ class DocumentCameraActivity : AppCompatActivity() {
}

override fun onPictureTaken(image: ImageRef, captureInfo: CaptureInfo) {
documentEnhancer.onSuccess { documentEnhancer ->
processPictureTaken(image, documentEnhancer)
documentStraightener.onSuccess { straightener ->
processPictureTaken(image, straightener)
}


Expand Down Expand Up @@ -134,10 +134,10 @@ class DocumentCameraActivity : AppCompatActivity() {
super.onPause()
}

private fun processPictureTaken(image: ImageRef, documentEnhancer: DocumentEnhancer) {
private fun processPictureTaken(image: ImageRef, documentStraightener: DocumentStraightener) {
// STRAIGHTEN SCANNED IMAGE ASSUMING DOCUMENT IS BENT
// Run document enhancer unwarping on original image:
val result = documentEnhancer.straighten(image, DocumentStraighteningParameters().apply {
// Run document straightening on original image:
val result = documentStraightener.run(image, DocumentStraighteningParameters().apply {
straighteningMode = DocumentStraighteningMode.STRAIGHTEN
// uncomment if you want wo set specific aspect ratios for documents
// aspectRatios = listOf(AspectRatio(29.0, 21.0))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ class MainActivity : AppCompatActivity() {
} ?: throw IllegalStateException("Cannot open input stream from URI: $uri")

// run document scanning on the image:
scanbotSdk.createDocumentEnhancer().getOrNull()
?.straighten(image, parameters = DocumentStraighteningParameters().apply {
scanbotSdk.createDocumentStraightener().getOrNull()
?.run(image, parameters = DocumentStraighteningParameters().apply {
straighteningMode = DocumentStraighteningMode.STRAIGHTEN
// uncomment if you want wo set specific aspect ratios for documents
// aspectRatios = listOf(AspectRatio(29.0, 21.0))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
android:id="@+id/show_doc_scanner_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scan document and enhance" />
android:text="Scan document and straighten" />

<Button
android:id="@+id/import_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Import image and enhance" />
android:text="Import image and straighten" />
</androidx.appcompat.widget.LinearLayoutCompat>

<ProgressBar
Expand Down
2 changes: 1 addition & 1 deletion classic-components-example/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ include(
":edit-polygon-view",
":camera-fragment",
":document-scanner",
":document-enhancer",
":document-straightener",
":barcode-scanner",
":mrz-scanner",
":mc-scanner",
Expand Down
2 changes: 1 addition & 1 deletion compose-custom-ui-example/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version")

def scanbotSdkVersion = "9.0.1"
def scanbotSdkVersion = "10.0.0.131-STAGING-SNAPSHOT"

implementation("io.scanbot:sdk-package-4:$scanbotSdkVersion")
implementation("io.scanbot:rtu-ui-v2-bundle:$scanbotSdkVersion")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
@file:kotlin.OptIn(ExperimentalPermissionsApi::class)

package io.scanbot.example.compose

import android.graphics.BitmapFactory
import android.net.Uri
import android.util.Log
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material3.Button
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import io.scanbot.sdk.image.ImageRef
import io.scanbot.sdk.imageprocessing.DocumentCleanupConfiguration
import io.scanbot.sdk.ui_v2.document.DocumentCleanupCustomUI
import io.scanbot.sdk.ui_v2.document.screen.documentcleanup.DocumentCleanupActionController
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
* Interactive demo screen for [DocumentCleanupCustomUI]. The user picks an image from the
* gallery, paints a mask on top of it and the masked regions are cleaned up by the SDK.
*
* For a code-only snippet (no image picker, no navigation), see
* [io.scanbot.example.compose.doc_code_snippet.document.DocumentCleanupCustomUISnippet].
*/
@Composable
fun DocumentCleanupScreen(navController: NavHostController) {
val context = LocalContext.current
val scope = rememberCoroutineScope()

var inputImage by remember { mutableStateOf<ImageRef?>(null) }
val controller = remember { mutableStateOf<DocumentCleanupActionController?>(null) }
val brushSize = remember { mutableFloatStateOf(40f) }

val activeController = controller.value
val canUndo = activeController?.canUndo?.collectAsState()?.value ?: false
val canRedo = activeController?.canRedo?.collectAsState()?.value ?: false
val progress = activeController?.progress?.collectAsState()?.value ?: false

val pickImageLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.PickVisualMedia()
) { uri: Uri? ->
if (uri == null) return@rememberLauncherForActivityResult
scope.launch {
val newImage = withContext(Dispatchers.IO) {
runCatching {
context.contentResolver.openInputStream(uri)?.use { stream ->
BitmapFactory.decodeStream(stream)
}
}.getOrNull()?.let { ImageRef.fromBitmap(it) }
}
if (newImage != null) {
inputImage?.close()
inputImage = newImage
} else {
Log.e("DocumentCleanupScreen", "Failed to load image from $uri")
}
}
}

Column(modifier = Modifier.fillMaxSize().systemBarsPadding()) {
Box(modifier = Modifier.fillMaxWidth().weight(1f)) {
val image = inputImage
if (image != null) {
DocumentCleanupCustomUI(
image = image,
modifier = Modifier.fillMaxSize(),
documentCleanupConfiguration = DocumentCleanupConfiguration(
keepText = true,
maxUndoRedoStackSize = 10,
),
brushSize = brushSize.floatValue.dp,
brushColor = Color.Red.copy(alpha = 0.5f),
onActionControllerCreated = { controller.value = it },
onResultImageChanged = {
Log.d("DocumentCleanupScreen", "New result image received")
},
onError = { error ->
Log.e("DocumentCleanupScreen", "Cleanup error", error)
},
)
if (progress) {
LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.TopCenter),
)
}
} else {
Box(modifier = Modifier.fillMaxSize()) {
Text(
text = "Pick an image to start cleanup",
modifier = Modifier.padding(16.dp),
)
}
}
}

Column(modifier = Modifier.fillMaxWidth().padding(8.dp)) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
) {
Button(
modifier = Modifier.weight(1f),
onClick = {
pickImageLauncher.launch(
PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)
)
},
) { Text("Pick image") }
}

Spacer(modifier = Modifier.height(8.dp))

Row(modifier = Modifier.fillMaxWidth()) {
Button(
modifier = Modifier.weight(1f),
enabled = canUndo && !progress,
onClick = { activeController?.undo() },
) { Text(text = "Undo", color = Color.White) }
Button(
modifier = Modifier.weight(1f),
enabled = canRedo && !progress,
onClick = { activeController?.redo() },
) { Text(text = "Redo", color = Color.White) }
Button(
modifier = Modifier.weight(1f),
enabled = canUndo && !progress,
onClick = { activeController?.reset() },
) { Text(text = "Reset", color = Color.White) }
}

Text(
modifier = Modifier.padding(top = 8.dp),
text = "Brush size: ${brushSize.floatValue.toInt()} dp",
)
Slider(
value = brushSize.floatValue,
onValueChange = { brushSize.floatValue = it },
valueRange = 8f..120f,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ sealed class Screen(val route: String) {
object BarcodeFindAndPick : Screen("BarcodeFindAndPick")

object DocumentScanner1 : Screen("DocumentScanner1")
object DocumentCleanup1 : Screen("DocumentCleanup1")
object MrzScanner1 : Screen("MrzScanner1")
data class BarcodeDetail(val data: String, val format: String) :
Screen("barcodeDetail/{data}/{format}") {
Expand All @@ -90,6 +91,7 @@ fun AppNavHost(navController: NavHostController) {
NavHost(navController = navController, startDestination = Screen.Menu.route) {
composable(Screen.Menu.route) { MenuScreen(navController) }
composable(Screen.DocumentScanner1.route) { DocumentScannerScreen(navController) }
composable(Screen.DocumentCleanup1.route) { DocumentCleanupScreen(navController) }
composable(Screen.MrzScanner1.route) { MrzScannerScreen(navController) }
composable(
route = "barcodeDetail/{data}/{format}",
Expand Down Expand Up @@ -122,6 +124,11 @@ fun MenuScreen(navController: NavHostController) {
Screen.DocumentScanner1.route,
""
),
Triple(
"Document Cleanup",
Screen.DocumentCleanup1.route,
""
),
Triple(
"MRZ Scanner",
Screen.MrzScanner1.route,
Expand Down
Loading