以下工具类实现了二维码的生成和添加 Logo 的功能。以下是对各部分功能的解释:
二维码生成:
通过 createQRCode() 方法来生成二维码图像。
它使用 QRCodeWriter 类来创建 BitMatrix 对象,该对象表示二维码的像素矩阵。
然后将 BitMatrix 转换为 Bitmap 对象。
zxing在生成二维码时,默认无法完全删除二维码白边,需要自定义BitMatrix,为其修改边框,该方法可以设置二维码的尺寸和二维码白边边距大小。
添加 Logo:
通过 addLogo() 方法在二维码图像上添加 Logo。 它使用**矩阵变换(缩放和平移)**来将 Logo 居中添加到二维码图像上。 这样可以在二维码图像上添加一个小的 Logo,使二维码的视觉效果更佳。
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.TypedValue;
import android.view.View;
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 java.util.HashMap;
import java.util.Map;
/**
* 二维码工具
*
* @author : jerome
*/
public class QRCodeUtil {
/**
* 用于创建一个二维码
*
* @param content
*/
public static Bitmap createQRCode(String content, Bitmap bm_logo, View view, int width, int margin) {
try {
int QR_WIDTH = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,width, view.getResources().getDisplayMetrics()) ; // 图像宽度
int QR_HEIGHT = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,width, view.getResources().getDisplayMetrics()) ; // 图像高度
//1,创建实例化对象
QRCodeWriter writer = new QRCodeWriter();
//2,设置字符集
Map<EncodeHintType, Object> map = new HashMap<EncodeHintType, Object>();
map.put(EncodeHintType.CHARACTER_SET, "UTF-8");
// map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//3,通过encode方法将内容写入矩阵对象
BitMatrix matrix;
matrix = writer.encode(content, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, map);
//设置二维码白边
matrix = updateBit(matrix,margin);
//4,定义一个二维码像素点的数组,向每个像素点中填充颜色
int[] pixels = new int[matrix.getWidth() * matrix.getHeight()];
for (int i = 0; i < matrix.getHeight(); i++) {
for (int j = 0; j < matrix.getWidth(); j++) {
// 如果矩阵此位置有值(是黑色部分)
if (matrix.get(j, i)) {
pixels[i * matrix.getWidth() + j] = 0xff000000;
// 如果矩阵此位置无值(是白色部分)
} else {
pixels[i * matrix.getWidth() + j] = 0xffffffff;
}
}
}
//6,创建一个指定高度和宽度的空白bitmap对象
Bitmap bm_QR = Bitmap.createBitmap(matrix.getWidth(), matrix.getHeight(), Bitmap.Config.ARGB_8888);
//7,将每个像素的颜色填充到bitmap对象
bm_QR.setPixels(pixels, 0, matrix.getWidth(), 0, 0, matrix.getWidth(), matrix.getHeight());
//9,创建一个方法在二维码上添加一张图片
if (null != bm_logo)
return addLogo(bm_QR, bm_logo);
else
return bm_QR;
} catch (WriterException e) {
e.printStackTrace();
}
return null;
}
/**
* 更新BitMatrix,为其增加边框。
*
* @param matrix 原始的BitMatrix对象。
* @param margin 边框的宽度(单位:像素)。
* @return 增加了边框的新BitMatrix对象。
*/
private static BitMatrix updateBit(BitMatrix matrix, int margin) {
int tempM = margin * 2;
int[] rec = matrix.getEnclosingRectangle(); // 获取二维码图案的属性
// rec[0]表示 left:二维码距离矩阵左边缘的距离
// rec[1]表示 top:二维码距离矩阵上边缘的距离
// rect[2]表示二维码的宽
// rect[2]表示二维码的高
int resWidth = rec[2] + tempM;
int resHeight = rec[3] + tempM;
BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); // 按照自定义边框生成新的BitMatrix
resMatrix.clear();
for (int i = margin; i < resWidth - margin; i++) { // 循环,将二维码图案绘制到新的bitMatrix中
for (int j = margin; j < resHeight - margin; j++) {
if (matrix.get(i - margin + rec[0], j - margin + rec[1])) {
resMatrix.set(i, j);
}
}
}
return resMatrix;
}
/**
* 添加 Logo 到二维码图片上
* <pre>
* 使用矩阵变换进行平移和缩放操作,确保 Logo 居中显示
* </pre>
* @param src 二维码图片
* @param logo Logo
* @return 含 Logo 二维码图片
*/
public static Bitmap addLogo(final Bitmap src, final Bitmap logo) {
if (src == null || logo == null) return src;
// 获取图片宽度高度
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
int logoWidth = logo.getWidth();
int logoHeight = logo.getHeight();
// 计算Logo要缩放的比例
float scaleFactor = Math.min(srcWidth * 1.0f / 6 / logoWidth, srcHeight * 1.0f / 6 / logoHeight);
// 创建一个新的Bitmap,用于绘制带Logo的二维码图片
Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(src, 0, 0, null);
// 创建一个Matrix对象,用于进行矩阵变换操作
Matrix matrix = new Matrix();
matrix.postScale(scaleFactor, scaleFactor);
// 计算Logo在二维码图片上的位置
int logoX = (srcWidth - (int) (logoWidth * scaleFactor)) / 2;
int logoY = (srcHeight - (int) (logoHeight * scaleFactor)) / 2;
// 对Logo进行矩阵变换,平移到指定位置并缩放
matrix.postTranslate(logoX, logoY);
canvas.drawBitmap(logo, matrix, null);
return bitmap;
}
}
定义ImageView:
<ImageView
android:id="@+id/codeView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
/>
调用方式:
QRCodeUtil.createQRCode(codeContent, logoBitmap, codeView, 295,2)