ZxingUtils
import android.graphics.Bitmap
import android.graphics.Canvas
import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType
import com.google.zxing.WriterException
import com.google.zxing.common.BitMatrix
import com.google.zxing.qrcode.QRCodeWriter
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import java.util.*
object ZxingUtils {
/**
* 生成二维码Bitmap
*
* @param content 内容
* @param widthPix 图片宽度
* @param heightPix 图片高度
* @param logoBm 二维码中心的Logo图标(可以为null)
* @return 生成二维码及保存文件是否成功
*/
fun createQRImage(content: String, widthPix: Int = 200, heightPix: Int = 200, logoBm: Bitmap? = null): Bitmap? {
try {
//配置参数
val hints: MutableMap<EncodeHintType, Any?> = HashMap()
hints[EncodeHintType.CHARACTER_SET] = "utf-8"
//容错级别
hints[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.H
//设置空白边距的宽度
hints[EncodeHintType.MARGIN] = 1 //default is 4
// 图像数据转换,使用了矩阵转换
var bitMatrix: BitMatrix? = null
try {
bitMatrix = QRCodeWriter().encode(
content, BarcodeFormat.QR_CODE, widthPix,
heightPix, hints
)
} catch (e: WriterException) {
e.printStackTrace()
}
val pixels = IntArray(widthPix * heightPix)
// 下面这里按照二维码的算法,逐个生成二维码的图片,
// 两个for循环是图片横列扫描的结果
for (y in 0 until heightPix) {
for (x in 0 until widthPix) {
if (bitMatrix!![x, y]) {
pixels[y * widthPix + x] = -0x1000000
} else {
pixels[y * widthPix + x] = -0x1
}
}
}
// 生成二维码图片的格式,使用ARGB_8888
var bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888)
bitmap!!.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix)
if (logoBm != null) {
bitmap = addLogo(bitmap, logoBm)
}
//必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,
// 内存消耗巨大!
return bitmap
// return bitmap != null && bitmap.compress(Bitmap.CompressFormat.JPEG, 100);
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
/**
* 在二维码中间添加Logo图案
*/
private fun addLogo(src: Bitmap?, logo: Bitmap?): Bitmap? {
if (src == null) {
return null
}
if (logo == null) {
return src
}
//获取图片的宽高
val srcWidth = src.width
val srcHeight = src.height
val logoWidth = logo.width
val logoHeight = logo.height
if (srcWidth == 0 || srcHeight == 0) {
return null
}
if (logoWidth == 0 || logoHeight == 0) {
return src
}
//logo大小为二维码整体大小的1/5
val scaleFactor = srcWidth * 1.0f / 5 / logoWidth
var bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888)
try {
val canvas = Canvas(bitmap!!)
canvas.drawBitmap(src, 0f, 0f, null)
canvas.scale(scaleFactor, scaleFactor, srcWidth / 2.toFloat(), srcHeight / 2.toFloat())
canvas.drawBitmap(
logo,
(srcWidth - logoWidth) / 2.toFloat(),
(srcHeight - logoHeight) / 2.toFloat(),
null
)
canvas.save()
canvas.restore()
} catch (e: Exception) {
bitmap = null
e.stackTrace
}
return bitmap
}
}