I'm using zxing in kotlin to read QR codes, and it works great, however I want to read QR codes with colors and it doesn't work, only black and white, how to do this?
this one reads it well,
this cannot be read,
CaptureActivityPortrait.kt
class CaptureActivityPortrait: CaptureActivity() {
}
build.graddle
implementation("com.journeyapps:zxing-android-embedded:4.3.0")
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="co.edu.ut.jrbustosm.calina"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.CAMERA" />
<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
....
<application
....
android:hardwareAccelerated="true"
....
>
<activity
android:name=".MainActivity"
....
android:screenOrientation="portrait"
tools:replace="android:screenOrientation"
....
>
....
</activity>
<activity
android:name=".CaptureActivityPortrait"
android:screenOrientation="sensorPortrait"
android:stateNotNeeded="true"
android:theme="@style/zxing_CaptureTheme"
android:windowSoftInputMode="stateAlwaysHidden" />
</application>
</manifest>
AnyFile.kt
val scanLauncher = rememberLauncherForActivityResult(
contract = ScanContract(),
) { result ->
if (result.contents != null) {/*do something with result*/}
}
val scanOptions = ScanOptions()
scanOptions.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
scanOptions.setOrientationLocked(true)
scanOptions.setPrompt("Reading QR code")
scanOptions.setBeepEnabled(false)
scanOptions.setCaptureActivity(CaptureActivityPortrait().javaClass)
scanLauncher.launch(scanOptions)
This seems to be by design in zxing
, which is the de-facto standard.
You could however create some pre-processing of the image. The more colors you support the more error-prone the solution will be. (ie. if there are more than two colors, the likelyhood of getting it wrong increases).
You could use the ColorMatrixColorFilter
in Kotlin and apply a ColorMatrix
to turn the bitmap into grayscale, and try reading it again.
See example here: Manipulate Visual Effects With the ColorMatrixFilter and ConvolutionFilter
If grayscale doesn't cut it, you will have to decide an arbitrary shade of grey – the threshold – that you will want to convert to white, and above it to black - to end up with the desired two colors only.
You could use ImageMagick via. kmagick that has a oneliner for exactly this purpose:
convert <input> -threshold xx% <output>
See other answers for tweaking: