From b66a8ca44d3d5cc5304b16aba6f17c2ca02177c9 Mon Sep 17 00:00:00 2001 From: Tamim Hossain <132823494+CodeWithTamim@users.noreply.github.com> Date: Fri, 25 Oct 2024 17:19:22 +0600 Subject: [PATCH] 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. --- .../com/v2ray/ang/util/QRCodeDecoder.kt | 83 ++++++------------- 1 file changed, 25 insertions(+), 58 deletions(-) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/QRCodeDecoder.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/QRCodeDecoder.kt index fb0643da..fb6b2f68 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/QRCodeDecoder.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/QRCodeDecoder.kt @@ -23,36 +23,19 @@ object QRCodeDecoder { * create qrcode using zxing */ fun createQRCode(text: String, size: Int = 800): Bitmap? { - try { - val hints = HashMap() - 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 } }