From 583477354eae21a4f79047af31003f977d4e1a79 Mon Sep 17 00:00:00 2001 From: dankito Date: Mon, 14 Mar 2022 03:02:11 +0100 Subject: [PATCH] Implemented drawing a border around QR code so that scanner apps can better detect QR code --- .../codinux/banking/epcqrcode/EpcQrCode.kt | 8 ++-- .../epcqrcode/EpcQrCodeStringFormatter.kt | 45 +++++++++++++++++-- .../NativeApp.kt | 2 +- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/EpcQrCode/src/commonMain/kotlin/net/codinux/banking/epcqrcode/EpcQrCode.kt b/EpcQrCode/src/commonMain/kotlin/net/codinux/banking/epcqrcode/EpcQrCode.kt index 6a8dc0b..eeeceb0 100644 --- a/EpcQrCode/src/commonMain/kotlin/net/codinux/banking/epcqrcode/EpcQrCode.kt +++ b/EpcQrCode/src/commonMain/kotlin/net/codinux/banking/epcqrcode/EpcQrCode.kt @@ -41,12 +41,12 @@ open class EpcQrCode( } - open fun qrCodeAsString(invertColors: Boolean = false): String { - return EpcQrCodeStringFormatter().asString(this, invertColors) + open fun qrCodeAsString(border: Int = 0, invertColors: Boolean = false): String { + return EpcQrCodeStringFormatter().asString(this, border, invertColors) } - open fun qrCodeAsSmallString(invertColors: Boolean = false): String { - return EpcQrCodeStringFormatter().asSmallString(this, invertColors) + open fun qrCodeAsSmallString(border: Int = 0, invertColors: Boolean = false): String { + return EpcQrCodeStringFormatter().asSmallString(this, border, invertColors) } diff --git a/EpcQrCode/src/commonMain/kotlin/net/codinux/banking/epcqrcode/EpcQrCodeStringFormatter.kt b/EpcQrCode/src/commonMain/kotlin/net/codinux/banking/epcqrcode/EpcQrCodeStringFormatter.kt index 24afaf3..b4b966a 100644 --- a/EpcQrCode/src/commonMain/kotlin/net/codinux/banking/epcqrcode/EpcQrCodeStringFormatter.kt +++ b/EpcQrCode/src/commonMain/kotlin/net/codinux/banking/epcqrcode/EpcQrCodeStringFormatter.kt @@ -14,14 +14,18 @@ open class EpcQrCodeStringFormatter { } - open fun asString(epcQrCode: EpcQrCode, invertColors: Boolean = false): String { + open fun asString(epcQrCode: EpcQrCode, border: Int = 0, invertColors: Boolean = false): String { val bitIsSetColor = if (invertColors) BitIsNotSetColor + BitIsNotSetColor else BitIsSetColor + BitIsSetColor val bitIsNotSetColor = if (invertColors) BitIsSetColor + BitIsSetColor else BitIsNotSetColor + BitIsNotSetColor val height = epcQrCode.height val width = epcQrCode.width val string = StringBuilder(height * width) + printBorderAboveOrBelow(border, width, string, bitIsNotSetColor) + for (y in 1 until height) { + printBorderBeforeOrAfter(border, string, bitIsNotSetColor) + for (x in 1 until width) { if (isBitSet(epcQrCode, x, y)) { string.append(bitIsSetColor) @@ -30,22 +34,30 @@ open class EpcQrCodeStringFormatter { } } + printBorderBeforeOrAfter(border, string, bitIsNotSetColor) + string.appendLine() } + printBorderAboveOrBelow(border, width, string, bitIsNotSetColor) + return string.toString() } - open fun asSmallString(epcQrCode: EpcQrCode, invertColors: Boolean = false): String { - val bitIsSetColor = if (invertColors) BitIsNotSetColor else BitIsSetColor + open fun asSmallString(epcQrCode: EpcQrCode, border: Int = 0, invertColors: Boolean = false): String { + val bitIsSetColor = if (invertColors) BitIsNotSetColor else BitIsSetColor val bitIsNotSetColor = if (invertColors) BitIsSetColor else BitIsNotSetColor val upperBitSetColor = if (invertColors) SmallSizeLowerBitSetColor else SmallSizeUpperBitSetColor val lowerBitSetColor = if (invertColors) SmallSizeUpperBitSetColor else SmallSizeLowerBitSetColor val height = epcQrCode.height val width = epcQrCode.width - val string = StringBuilder(height * width) + val string = StringBuilder((height + border) * (width + border)) + + printBorderAboveOrBelow(border, width, string, bitIsNotSetColor) for (y in 1 until height - 1 step 2) { + printBorderBeforeOrAfter(border, string, bitIsNotSetColor) + for (x in 1 until width) { val currentRowBit = epcQrCode.getColorCodeAt(x, y) val nextRowBit = epcQrCode.getColorCodeAt(x, y + 1) @@ -65,10 +77,14 @@ open class EpcQrCodeStringFormatter { } } + printBorderBeforeOrAfter(border, string, bitIsNotSetColor) + string.appendLine() } if (height % 2 == 0) { // if last row is odd + printBorderBeforeOrAfter(border, string, bitIsNotSetColor) + val y = height - 1 for (x in 1 until width) { if (isBitSet(epcQrCode, x, y)) { @@ -78,9 +94,13 @@ open class EpcQrCodeStringFormatter { } } + printBorderBeforeOrAfter(border, string, bitIsNotSetColor) + string.appendLine() } + printBorderAboveOrBelow(border, width, string, bitIsNotSetColor) + return string.toString() } @@ -95,4 +115,21 @@ open class EpcQrCodeStringFormatter { return qrCodeBitColorCode < -1 } + + private fun printBorderAboveOrBelow(border: Int, width: Int, string: StringBuilder, bitIsNotSetColor: String) { + for (y in 0 until border) { + for (x in 1 until width + 2 * (border * 2)) { + string.append(bitIsNotSetColor) + } + + string.appendLine() + } + } + + private fun printBorderBeforeOrAfter(border: Int, string: StringBuilder, bitIsNotSetColor: String) { + for (x in 0 until (border * 2)) { + string.append(bitIsNotSetColor) + } + } + } \ No newline at end of file diff --git a/EpcQrCodeNativeApp/src/nativeMain/kotlin/net.codinux.banking.epcqrcode/NativeApp.kt b/EpcQrCodeNativeApp/src/nativeMain/kotlin/net.codinux.banking.epcqrcode/NativeApp.kt index 78bb5bb..6c3da7c 100644 --- a/EpcQrCodeNativeApp/src/nativeMain/kotlin/net.codinux.banking.epcqrcode/NativeApp.kt +++ b/EpcQrCodeNativeApp/src/nativeMain/kotlin/net.codinux.banking.epcqrcode/NativeApp.kt @@ -6,7 +6,7 @@ class NativeApp { fun generateAndShowEpcQrCode(config: EpcQrCodeConfig) { val epcQrCode = EpcQrCodeGenerator().generateEpcQrCode(config, 40) - println(epcQrCode.qrCodeAsSmallString()) + println(epcQrCode.qrCodeAsSmallString(4, true)) } } \ No newline at end of file