package safeluck.drive.evaluation.util; import android.graphics.Bitmap; import android.graphics.Canvas; import android.text.TextUtils; import androidx.annotation.Nullable; 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.Hashtable; /** * @ProjectName: DriveJudge * @Package: safeluck.drive.evaluation.util * @ClassName: QRCodeUtil * @Description: 二维码生成工具 * @Author: 李占伟 * @CreateDate: 2020-04-10 15:58 * @UpdateUser: 更新者 * @UpdateDate: 2020-04-10 15:58 * @UpdateRemark: 更新说明 * @Version: 1.0 */ public class QRCodeUtil { /** * 生成自定义二维码 * * @param content 字符串内容 * @param width 二维码宽度 * @param height 二维码高度 * @param character_set 编码方式(一般使用UTF-8) * @param error_correction_level 容错率 L:7% M:15% Q:25% H:35% * @param margin 空白边距(二维码与边框的空白区域) * @param color_black 黑色色块 * @param color_white 白色色块 * @param logoBitmap logo图片(传null时不添加logo) * @param logoPercent logo所占百分比 * @param bitmap_black 用来代替黑色色块的图片(传null时不代替) * @return */ public static Bitmap createQRCodeBitmap(String content, int width, int height, String character_set, String error_correction_level, String margin, int color_black, int color_white, Bitmap logoBitmap, float logoPercent, Bitmap bitmap_black) { // 字符串内容判空 if (TextUtils.isEmpty(content)) { return null; } // 宽和高>=0 if (width < 0 || height < 0) { return null; } try { /** 1.设置二维码相关配置,生成BitMatrix(位矩阵)对象 */ Hashtable hints = new Hashtable<>(); // 字符转码格式设置 if (!TextUtils.isEmpty(character_set)) { hints.put(EncodeHintType.CHARACTER_SET, character_set); } // 容错率设置 if (!TextUtils.isEmpty(error_correction_level)) { hints.put(EncodeHintType.ERROR_CORRECTION, error_correction_level); } // 空白边距设置 if (!TextUtils.isEmpty(margin)) { hints.put(EncodeHintType.MARGIN, margin); } /** 2.将配置参数传入到QRCodeWriter的encode方法生成BitMatrix(位矩阵)对象 */ BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints); /** 3.创建像素数组,并根据BitMatrix(位矩阵)对象为数组元素赋颜色值 */ if (bitmap_black != null) { //从当前位图按一定的比例创建一个新的位图 bitmap_black = Bitmap.createScaledBitmap(bitmap_black, width, height, false); } int[] pixels = new int[width * height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { //bitMatrix.get(x,y)方法返回true是黑色色块,false是白色色块 if (bitMatrix.get(x, y)) {// 黑色色块像素设置 if (bitmap_black != null) {//图片不为null,则将黑色色块换为新位图的像素。 pixels[y * width + x] = bitmap_black.getPixel(x, y); } else { pixels[y * width + x] = color_black; } } else { pixels[y * width + x] = color_white;// 白色色块像素设置 } } } /** 4.创建Bitmap对象,根据像素数组设置Bitmap每个像素点的颜色值,并返回Bitmap对象 */ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, width, 0, 0, width, height); /** 5.为二维码添加logo图标 */ if (logoBitmap != null) { return addLogo(bitmap, logoBitmap, logoPercent); } return bitmap; } catch (WriterException e) { e.printStackTrace(); return null; } } /** * 向二维码中间添加logo图片(图片合成) * * @param srcBitmap 原图片(生成的简单二维码图片) * @param logoBitmap logo图片 * @param logoPercent 百分比 (用于调整logo图片在原图片中的显示大小, 取值范围[0,1] ) * 原图片是二维码时,建议使用0.2F,百分比过大可能导致二维码扫描失败。 * @return */ @Nullable private static Bitmap addLogo(@Nullable Bitmap srcBitmap, @Nullable Bitmap logoBitmap, float logoPercent) { if (srcBitmap == null) { return null; } if (logoBitmap == null) { return srcBitmap; } //传值不合法时使用0.2F if (logoPercent < 0F || logoPercent > 1F) { logoPercent = 0.2F; } /** 1. 获取原图片和Logo图片各自的宽、高值 */ int srcWidth = srcBitmap.getWidth(); int srcHeight = srcBitmap.getHeight(); int logoWidth = logoBitmap.getWidth(); int logoHeight = logoBitmap.getHeight(); /** 2. 计算画布缩放的宽高比 */ float scaleWidth = srcWidth * logoPercent / logoWidth; float scaleHeight = srcHeight * logoPercent / logoHeight; /** 3. 使用Canvas绘制,合成图片 */ Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.drawBitmap(srcBitmap, 0, 0, null); canvas.scale(scaleWidth, scaleHeight, srcWidth / 2, srcHeight / 2); canvas.drawBitmap(logoBitmap, srcWidth / 2 - logoWidth / 2, srcHeight / 2 - logoHeight / 2, null); return bitmap; } }