概述
二维码的应用已经可以说是非常广泛了,那么如何在当前的app项目中生成自定义二维码,本文对采用Google开源库Zxing去生成二维码的流程进行简单说明。
系列文章:
Android二维码的基础使用(一):利用Zxing生成自定义二维码
Android二维码的基础使用(二):保存和分享
Android二维码的基础使用(三):二维码扫描Demo实现
使用
1. 引入jar包
build.gradle文件中引入jar包。
implementation 'com.google.zxing:core:3.3.0'
2. 基本使用
生成一个二维码主要包含如下几个步骤:
- 设置二维码的配置,如字符转码格式。容错率以及空白边距等等参数。
- 通过
QRWriter
生成位矩阵BitMatrix
对象 - 创建像素数组,并根据位矩阵对象逐项赋值颜色。
- 根据像素数组创建bitmap对象生成二维码图片。
示例代码如下:
/**
* 生成简单二维码
*
* @param content 字符串内容
* @param width 二维码宽度
* @param height 二维码高度
* @param characterSet 编码方式(一般使用UTF-8)
* @param errorCorrectionLevel 容错率 L:7% M:15% Q:25% H:35%
* @param margin 空白边距(二维码与边框的空白区域)
* @param colorBlack 黑色色块
* @param colorWhite 白色色块
* @return BitMap
*/
fun createQRCodeBitmap(
content: String?, width: Int, height: Int,
characterSet: String?, errorCorrectionLevel: String?,
margin: String?, colorBlack: Int, colorWhite: Int
): Bitmap? {
// 字符串内容判空
if (TextUtils.isEmpty(content)) {
return null
}
// 宽和高>=0
if (width < 0 || height < 0) {
return null
}
return try {
/** 1.设置二维码相关配置 */
val hints =
Hashtable<EncodeHintType, String?>()
// 字符转码格式设置
if (!TextUtils.isEmpty(characterSet)) {
hints[EncodeHintType.CHARACTER_SET] = characterSet
}
// 容错率设置
if (!TextUtils.isEmpty(errorCorrectionLevel)) {
hints[EncodeHintType.ERROR_CORRECTION] = errorCorrectionLevel
}
// 空白边距设置
if (!TextUtils.isEmpty(margin)) {
hints[EncodeHintType.MARGIN] = margin
}
/** 2.将配置参数传入到QRCodeWriter的encode方法生成BitMatrix(位矩阵)对象 */
val bitMatrix =
QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints)
/** 3.创建像素数组,并根据BitMatrix(位矩阵)对象为数组元素赋颜色值 */
val pixels = IntArray(width * height)
for (y in 0 until height) {
for (x in 0 until width) {
//bitMatrix.get(x,y)方法返回true是黑色色块,false是白色色块
if (bitMatrix[x, y]) {
pixels[y * width + x] = colorBlack //黑色色块像素设置,可以通过传入不同的颜色实现彩色二维码,例如Color.argb(1,55,206,141)等设置不同的颜色。
} else {
pixels[y * width + x] = colorWhite // 白色色块像素设置
}
}
}
/** 4.创建Bitmap对象,根据像素数组设置Bitmap每个像素点的颜色值,并返回Bitmap对象 */
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
bitmap.setPixels(pixels, 0, width, 0, 0, width, height)
bitmap
} catch (e: WriterException) {
e.printStackTrace()
null
}
//调用示例代码
// imageView.setImageBitmap(QRCodeBitmap.newInstance().createQRCodeBitmap("test",80,80,
// "UTF-8","L","1", Color.BLACK,Color.WHITE));
}
参数说明:
- characterSet:编码方式,通常采用UTF-8,格式不对可能会导致乱码。
- errorCorrectionLevel:容错率,即使二维码破损了一部分也能扫描的程度,容错率越高,二维码能存储的内容也会随之变小。主要等级分为:L:7% M:15% Q:25% H:35%。
- 颜色:颜色对应二维码生成时的颜色显示,可以通过设置不用的颜色来实现彩色二维码,如
Color.argb(1,55,206,141)
3. 二维码嵌入logo
常见的二维码中还可以嵌入logo,添加logo就是图片合成,将logo图片以一定比例合成在原二维码图片上,即将logo图片直接拼接在二维码的中心位置,示例代码如下:
/***
* 为二维码添加logo
*
* @param srcBitmap 二维码图片
* @param logoBitmap logo图片
* @param percent logo比例
* @return 生成的最终的图片
*/
fun addLogo(srcBitmap: Bitmap?, logoBitmap: Bitmap?, percent: Float): Bitmap? {
//判断参数是否正确
if (srcBitmap == null)
return null
if (logoBitmap == null)
return srcBitmap
//输入logo图片比例错误自动纠正为默认的0.2f
var logoPercent = percent
if (percent < 0 || percent > 1)
logoPercent = 0.2f
//分别获取bitmap图片的大小
var sHeight = srcBitmap.height
var sWidth = srcBitmap.width
var lHeight = logoBitmap.height
var lWidth = logoBitmap.width
//获取缩放比例
var scareWidth = sHeight * logoPercent / lWidth
var scareHeight = sWidth * logoPercent / lHeight
//使用canvas重新绘制bitmap
var bitmap = Bitmap.createBitmap(sWidth, sHeight, Bitmap.Config.ARGB_8888)
var canvas = Canvas(bitmap)
canvas.drawBitmap(srcBitmap, 0f, 0f, null)
canvas.scale(
scareWidth,
scareHeight,
(sWidth / 2).toFloat(),
(sHeight / 2).toFloat()
) //设置缩放中心基点
canvas.drawBitmap(
logoBitmap,
(sWidth/2 - lWidth / 2).toFloat(),
(sHeight/2 - lHeight / 2).toFloat(),
null
)
return bitmap
}
4. 添加图片展示效果
和生成不同颜色的二维码本质相同,其实现的基本逻辑就是在绘制二维码的时候使用图片的像素块去取代当前二维码的非白色的像素块,其他的步骤和基本生成二维码的流程没有区别,部分示例代码如下:
//bitmapOther为传入的需要展示的图片效果的图片,类型为bitmap
//先根据二维码的大小生成等大的bitmap,方便直接获取对应的像素块
var bitmapExtra: Bitmap? = null
if (bitmapOther != null) {
bitmapExtra = Bitmap.createScaledBitmap(bitmapOther, width, height, false)
}
...
if (bitMatrix.get(x, y)) {// 像素块设置
if (bitmapExtra != null) {
//图片不为null,则将黑色色块换为新位图的像素。
pixels[y * width + x] = bitmapExtra.getPixel(x, y);
} else {
//无图片时默认仍然为输入颜色像素块
pixels[y * width + x] = colorBlack;
}
} else {
pixels[y * width + x] = colorWhite;// 白色色块像素设置
}
如果图片的大部分颜色都比较浅,使用上述方法会影响到扫描效果,如果需要使用二维码上附加图片效果,尽量使用颜色较深的图片。