Skip to content

Dong-Lin/KScan

 
 

Repository files navigation

License Latest release Latest build

KScan


Compose Multiplatform Barcode Scanning Library

Platform Android Platform iOS


Android iOS

KScan is a Compose Multiplatform library that makes it easy to scan barcodes in your apps


To integrate KScan into your project

Using JitPack (Recommended)

Add JitPack repository in your settings.gradle.kts:

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven("https://jitpack.io")
    }
}

Add the dependency in your common module's commonMain source set:

implementation("com.github.Dong-Lin:KScan:0.3.2")

Using Maven Central

implementation("io.github.Dong-Lin:KScan:0.3.2")

Note: This is a fork of ismai117/KScan with added ROI support. See SETUP.md for detailed integration instructions.


Android - MLKit

  • Uses Google’s MLKit library for barcode scanning on Android

iOS - AVFoundation

  • Utilizes Apple’s AVFoundation framework for camera setup and barcode scanning on iOS

Important: iOS requires you to add the "Privacy - Camera Usage Description" key to your Info.plist file inside xcode, you need to provide a reason for why you want to access the camera.

Basic Usage

To use KScan, simply add the ScannerView in your app like this:

if (showScanner) {
    ScannerView(
        codeTypes = listOf(
            BarcodeFormats.FORMAT_QR_CODE,
            BarcodeFormats.FORMAT_EAN_13,
        )
    ) { result ->
        when (result) {
            is BarcodeResult.OnSuccess -> {
                println("Barcode: ${result.barcode.data}, format: ${result.barcode.format}")
            }
            is BarcodeResult.OnFailed -> {
                println("error: ${result.exception.message}")
            }
            BarcodeResult.OnCanceled -> {
                println("scan canceled")
            }
        }
    }
}

To dismiss the scanner, you need to manage your own state, set it to false in the right places inside the ScannerView block after you handle the results

if (showScanner) {
    ScannerView(
        codeTypes = listOf(
            BarcodeFormats.FORMAT_QR_CODE,
            BarcodeFormats.FORMAT_EAN_13,
        )
    ) { result ->
        when (result) {
            is BarcodeResult.OnSuccess -> {
                println("Barcode: ${result.barcode.data}, format: ${result.barcode.format}")
                showScanner = false
            }
            is BarcodeResult.OnFailed -> {
                println("Error: ${result.exception.message}")
                showScanner = false
            }
            BarcodeResult.OnCanceled -> {
                showScanner = false
            }
        }
    }
}

If you want to remove the UI and just use the raw scanner, you can set the showUi parameter to false

if (showScanner) {
    ScannerView(
        codeTypes = listOf(
            BarcodeFormats.FORMAT_QR_CODE,
            BarcodeFormats.FORMAT_EAN_13,
        ),
        showUi = false
    ) { result ->
        when (result) {
            is BarcodeResult.OnSuccess -> {
                println("Barcode: ${result.barcode.data}, format: ${result.barcode.format}")
                showScanner = false
            }
            is BarcodeResult.OnFailed -> {
                println("Error: ${result.exception.message}")
                showScanner = false
            }
            BarcodeResult.OnCanceled -> {
                showScanner = false
            }
        }
    }
}

Region of Interest (ROI)

You can restrict barcode scanning to a specific region of the camera preview using scanRegion. This improves performance and accuracy by only detecting barcodes within the defined area:

// Define a centered scan region (60% width, 40% height)
val scanRegion = ScanRegion.centered(
    width = 0.6f,
    height = 0.4f
)

if (showScanner) {
    ScannerView(
        codeTypes = listOf(BarcodeFormats.FORMAT_QR_CODE),
        scanRegion = scanRegion  // Only detect barcodes in this region
    ) { result ->
        // Handle result
    }
}

You can also create custom regions:

// Custom region: top-right corner
val customRegion = ScanRegion(
    left = 0.5f,   // Start at 50% from left
    top = 0.1f,    // Start at 10% from top
    width = 0.4f,  // 40% width
    height = 0.3f  // 30% height
)

When a scan region is specified, the UI will automatically show a visual overlay highlighting the active scanning area.

Custom Scanner UI

To build a custom scanner UI with torch and zoom control, set showUi = false and use a ScannerController.

val scannerController = remember { ScannerController() }

if (showScanner) {
    ScannerView(
        codeTypes = listOf(BarcodeFormat.FORMAT_ALL_FORMATS),
        showUi = false,
        scannerController = scannerController
    ) { result ->
        when (result) {
            is BarcodeResult.OnSuccess -> {
                println("Barcode: ${result.barcode.data}, format: ${result.barcode.format}")
                showScanner = false
            }
            is BarcodeResult.OnFailed -> {
                println("Error: ${result.exception.message}")
                showScanner = false
            }
            BarcodeResult.OnCanceled -> {
                showScanner = false
            }
        }
    }

    Column(
        modifier = Modifier.align(Alignment.BottomCenter).padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Button(onClick = {
            scannerController.setTorch(!scannerController.torchEnabled)
        }) {
            Text("Torch ${if (scannerController.torchEnabled) "Off" else "On"}")
        }
        Slider(
            value = scannerController.zoomRatio,
            onValueChange = scannerController::setZoom,
            valueRange = 1f..scannerController.maxZoomRatio
        )
    }
}

Contributing

If you’d like to contribute, whether it’s fixing bugs, improving documentation, adding features, or helping with maintenance, your support is greatly appreciated!

About

Compose Multiplatform Barcode Scanning

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Kotlin 98.6%
  • Other 1.4%