-
-
Save SherifMuSherif/c305efdd0f8cab7ba3b41cf9149455ea to your computer and use it in GitHub Desktop.
A function to encode text as a QR code using BitmapPainter and zxing-core for use in Jetpack Compose with Image composable. Note: This function has been optimized to set all pixels at once using setPixels, which significantly improves performance, especially when used in a LazyColumn. Thanks @dev-niiaddy!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun rememberQrBitmapPainter( | |
content: String, | |
size: Dp = 150.dp, | |
padding: Dp = 0.dp | |
): BitmapPainter { | |
val density = LocalDensity.current | |
val sizePx = with(density) { size.roundToPx() } | |
val paddingPx = with(density) { padding.roundToPx() } | |
var bitmap by remember(content) { | |
mutableStateOf<Bitmap?>(null) | |
} | |
LaunchedEffect(bitmap) { | |
if (bitmap != null) return@LaunchedEffect | |
launch(Dispatchers.IO) { | |
val qrCodeWriter = QRCodeWriter() | |
val encodeHints = mutableMapOf<EncodeHintType, Any?>() | |
.apply { | |
this[EncodeHintType.MARGIN] = paddingPx | |
} | |
val bitmapMatrix = try { | |
qrCodeWriter.encode( | |
content, BarcodeFormat.QR_CODE, | |
sizePx, sizePx, encodeHints | |
) | |
} catch (ex: WriterException) { | |
null | |
} | |
val matrixWidth = bitmapMatrix?.width ?: sizePx | |
val matrixHeight = bitmapMatrix?.height ?: sizePx | |
val newBitmap = Bitmap.createBitmap( | |
bitmapMatrix?.width ?: sizePx, | |
bitmapMatrix?.height ?: sizePx, | |
Bitmap.Config.ARGB_8888, | |
) | |
val pixels = IntArray(matrixWidth * matrixHeight) | |
for (x in 0 until matrixWidth) { | |
for (y in 0 until matrixHeight) { | |
val shouldColorPixel = bitmapMatrix?.get(x, y) ?: false | |
val pixelColor = if (shouldColorPixel) Color.BLACK else Color.WHITE | |
pixels[y * matrixWidth + x] = pixelColor | |
} | |
} | |
newBitmap.setPixels(pixels, 0, matrixWidth, 0, 0, matrixWidth, matrixHeight) | |
bitmap = newBitmap | |
} | |
} | |
return remember(bitmap) { | |
val currentBitmap = bitmap ?: Bitmap.createBitmap( | |
sizePx, sizePx, | |
Bitmap.Config.ARGB_8888, | |
).apply { eraseColor(Color.TRANSPARENT) } | |
BitmapPainter(currentBitmap.asImageBitmap()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment