概述
二維碼的應(yīng)用已經(jīng)可以說是非常廣泛了熊昌,那么如何在當(dāng)前的app項目中生成自定義二維碼,本文對采用Google開源庫Zxing去生成二維碼的流程進(jìn)行簡單說明裕膀。
系列文章:
Android二維碼的基礎(chǔ)使用(一):利用Zxing生成自定義二維碼
Android二維碼的基礎(chǔ)使用(二):保存和分享
Android二維碼的基礎(chǔ)使用(三):二維碼掃描Demo實現(xiàn)
使用
1. 引入jar包
build.gradle文件中引入jar包纹因。
implementation 'com.google.zxing:core:3.3.0'
2. 基本使用
生成一個二維碼主要包含如下幾個步驟:
- 設(shè)置二維碼的配置,如字符轉(zhuǎn)碼格式杠茬。容錯率以及空白邊距等等參數(shù)遂填。
- 通過
QRWriter
生成位矩陣BitMatrix
對象 - 創(chuàng)建像素數(shù)組,并根據(jù)位矩陣對象逐項賦值顏色澈蝙。
- 根據(jù)像素數(shù)組創(chuàng)建bitmap對象生成二維碼圖片。
示例代碼如下:
/**
* 生成簡單二維碼
*
* @param content 字符串內(nèi)容
* @param width 二維碼寬度
* @param height 二維碼高度
* @param characterSet 編碼方式(一般使用UTF-8)
* @param errorCorrectionLevel 容錯率 L:7% M:15% Q:25% H:35%
* @param margin 空白邊距(二維碼與邊框的空白區(qū)域)
* @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? {
// 字符串內(nèi)容判空
if (TextUtils.isEmpty(content)) {
return null
}
// 寬和高>=0
if (width < 0 || height < 0) {
return null
}
return try {
/** 1.設(shè)置二維碼相關(guān)配置 */
val hints =
Hashtable<EncodeHintType, String?>()
// 字符轉(zhuǎn)碼格式設(shè)置
if (!TextUtils.isEmpty(characterSet)) {
hints[EncodeHintType.CHARACTER_SET] = characterSet
}
// 容錯率設(shè)置
if (!TextUtils.isEmpty(errorCorrectionLevel)) {
hints[EncodeHintType.ERROR_CORRECTION] = errorCorrectionLevel
}
// 空白邊距設(shè)置
if (!TextUtils.isEmpty(margin)) {
hints[EncodeHintType.MARGIN] = margin
}
/** 2.將配置參數(shù)傳入到QRCodeWriter的encode方法生成BitMatrix(位矩陣)對象 */
val bitMatrix =
QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints)
/** 3.創(chuàng)建像素數(shù)組,并根據(jù)BitMatrix(位矩陣)對象為數(shù)組元素賦顏色值 */
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 //黑色色塊像素設(shè)置灯荧,可以通過傳入不同的顏色實現(xiàn)彩色二維碼,例如Color.argb(1,55,206,141)等設(shè)置不同的顏色盐杂。
} else {
pixels[y * width + x] = colorWhite // 白色色塊像素設(shè)置
}
}
}
/** 4.創(chuàng)建Bitmap對象,根據(jù)像素數(shù)組設(shè)置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
}
//調(diào)用示例代碼
// imageView.setImageBitmap(QRCodeBitmap.newInstance().createQRCodeBitmap("test",80,80,
// "UTF-8","L","1", Color.BLACK,Color.WHITE));
}
參數(shù)說明:
- characterSet:編碼方式逗载,通常采用UTF-8,格式不對可能會導(dǎo)致亂碼链烈。
- errorCorrectionLevel:容錯率厉斟,即使二維碼破損了一部分也能掃描的程度,容錯率越高强衡,二維碼能存儲的內(nèi)容也會隨之變小擦秽。主要等級分為:L:7% M:15% Q:25% H:35%。
- 顏色:顏色對應(yīng)二維碼生成時的顏色顯示漩勤,可以通過設(shè)置不用的顏色來實現(xiàn)彩色二維碼感挥,如
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? {
//判斷參數(shù)是否正確
if (srcBitmap == null)
return null
if (logoBitmap == null)
return srcBitmap
//輸入logo圖片比例錯誤自動糾正為默認(rèn)的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()
) //設(shè)置縮放中心基點
canvas.drawBitmap(
logoBitmap,
(sWidth/2 - lWidth / 2).toFloat(),
(sHeight/2 - lHeight / 2).toFloat(),
null
)
return bitmap
}
4. 添加圖片展示效果
和生成不同顏色的二維碼本質(zhì)相同究飞,其實現(xiàn)的基本邏輯就是在繪制二維碼的時候使用圖片的像素塊去取代當(dāng)前二維碼的非白色的像素塊置谦,其他的步驟和基本生成二維碼的流程沒有區(qū)別堂鲤,部分示例代碼如下:
//bitmapOther為傳入的需要展示的圖片效果的圖片,類型為bitmap
//先根據(jù)二維碼的大小生成等大的bitmap媒峡,方便直接獲取對應(yīng)的像素塊
var bitmapExtra: Bitmap? = null
if (bitmapOther != null) {
bitmapExtra = Bitmap.createScaledBitmap(bitmapOther, width, height, false)
}
...
if (bitMatrix.get(x, y)) {// 像素塊設(shè)置
if (bitmapExtra != null) {
//圖片不為null瘟栖,則將黑色色塊換為新位圖的像素。
pixels[y * width + x] = bitmapExtra.getPixel(x, y);
} else {
//無圖片時默認(rèn)仍然為輸入顏色像素塊
pixels[y * width + x] = colorBlack;
}
} else {
pixels[y * width + x] = colorWhite;// 白色色塊像素設(shè)置
}
如果圖片的大部分顏色都比較淺丝蹭,使用上述方法會影響到掃描效果慢宗,如果需要使用二維碼上附加圖片效果,盡量使用顏色較深的圖片奔穿。