Refactor QRCodeDecoder for readability and performance (#3782)
- Improved the `createQRCode` function by replacing manual loops with Kotlin idioms and using `runCatching` for safer error handling. - Refactored `syncDecodeQRCode` to simplify control flow and avoid redundant null checks. - Enhanced error handling and logging by using `runCatching` and more concise exception handling.
This commit is contained in:
@@ -23,36 +23,19 @@ object QRCodeDecoder {
|
||||
* create qrcode using zxing
|
||||
*/
|
||||
fun createQRCode(text: String, size: Int = 800): Bitmap? {
|
||||
try {
|
||||
val hints = HashMap<EncodeHintType, String>()
|
||||
hints[EncodeHintType.CHARACTER_SET] = "utf-8"
|
||||
val bitMatrix = QRCodeWriter().encode(
|
||||
text,
|
||||
BarcodeFormat.QR_CODE, size, size, hints
|
||||
)
|
||||
val pixels = IntArray(size * size)
|
||||
for (y in 0 until size) {
|
||||
for (x in 0 until size) {
|
||||
if (bitMatrix.get(x, y)) {
|
||||
pixels[y * size + x] = 0xff000000.toInt()
|
||||
} else {
|
||||
pixels[y * size + x] = 0xffffffff.toInt()
|
||||
}
|
||||
|
||||
}
|
||||
return runCatching {
|
||||
val hints = mapOf(EncodeHintType.CHARACTER_SET to Charsets.UTF_8)
|
||||
val bitMatrix = QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, size, size, hints)
|
||||
val pixels = IntArray(size * size) { i ->
|
||||
if (bitMatrix.get(i % size, i / size)) 0xff000000.toInt() else 0xffffffff.toInt()
|
||||
}
|
||||
val bitmap = Bitmap.createBitmap(
|
||||
size, size,
|
||||
Bitmap.Config.ARGB_8888
|
||||
)
|
||||
bitmap.setPixels(pixels, 0, size, 0, 0, size, size)
|
||||
return bitmap
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return null
|
||||
}
|
||||
Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888).apply {
|
||||
setPixels(pixels, 0, size, 0, 0, size, size)
|
||||
}
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 同步解析本地图片二维码。该方法是耗时操作,请在子线程中调用。
|
||||
*
|
||||
@@ -70,40 +53,24 @@ object QRCodeDecoder {
|
||||
* @return 返回二维码图片里的内容 或 null
|
||||
*/
|
||||
fun syncDecodeQRCode(bitmap: Bitmap?): String? {
|
||||
if (bitmap == null) {
|
||||
return null
|
||||
}
|
||||
var source: RGBLuminanceSource? = null
|
||||
try {
|
||||
val width = bitmap.width
|
||||
val height = bitmap.height
|
||||
val pixels = IntArray(width * height)
|
||||
bitmap.getPixels(pixels, 0, width, 0, 0, width, height)
|
||||
source = RGBLuminanceSource(width, height, pixels)
|
||||
val qrReader = QRCodeReader()
|
||||
try {
|
||||
val result = try {
|
||||
qrReader.decode(
|
||||
BinaryBitmap(GlobalHistogramBinarizer(source)),
|
||||
mapOf(DecodeHintType.TRY_HARDER to true)
|
||||
)
|
||||
} catch (e: NotFoundException) {
|
||||
qrReader.decode(
|
||||
BinaryBitmap(GlobalHistogramBinarizer(source.invert())),
|
||||
mapOf(DecodeHintType.TRY_HARDER to true)
|
||||
)
|
||||
return bitmap?.let {
|
||||
runCatching {
|
||||
val pixels = IntArray(it.width * it.height).also { array ->
|
||||
it.getPixels(array, 0, it.width, 0, 0, it.width, it.height)
|
||||
}
|
||||
return result.text
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
val source = RGBLuminanceSource(it.width, it.height, pixels)
|
||||
val qrReader = QRCodeReader()
|
||||
|
||||
return null
|
||||
try {
|
||||
qrReader.decode(BinaryBitmap(GlobalHistogramBinarizer(source)), mapOf(DecodeHintType.TRY_HARDER to true)).text
|
||||
} catch (e: NotFoundException) {
|
||||
qrReader.decode(BinaryBitmap(GlobalHistogramBinarizer(source.invert())), mapOf(DecodeHintType.TRY_HARDER to true)).text
|
||||
}
|
||||
}.getOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将本地图片文件转换成可解码二维码的 Bitmap。为了避免图片太大,这里对图片进行了压缩。感谢 https://github.com/devilsen 提的 PR
|
||||
*
|
||||
@@ -149,6 +116,6 @@ object QRCodeDecoder {
|
||||
)
|
||||
HINTS[DecodeHintType.TRY_HARDER] = BarcodeFormat.QR_CODE
|
||||
HINTS[DecodeHintType.POSSIBLE_FORMATS] = allFormats
|
||||
HINTS[DecodeHintType.CHARACTER_SET] = "utf-8"
|
||||
HINTS[DecodeHintType.CHARACTER_SET] = Charsets.UTF_8
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user