Android 生成二维码

一、生成二维码工具类封装

1、二维码库

复制代码
  // 二维码
    implementation 'com.journeyapps:zxing-android-embedded:4.3.0'

2、工具类

复制代码
/**
 * 二维码
 * 处理工具
 */

public class QRCodeDealUtils {

    /**
     * @param content     字符串内容
     * @param size        位图宽&高(单位:px)
     * @param logo        二维码logo
     * @param logoPercent 二维码logo的占比 [0,1]
     * @return
     */
    public static Bitmap createQRCodeBitmapLogo(String content, int size, Bitmap logo, float logoPercent) {
        Bitmap qrCodeBitmap = null;
        Bitmap bitmap;
        try {
            // 不带logo二维码
            qrCodeBitmap = generateQRCodeWithoutMargin(content, size, size);
            // 带logo 二维码
            bitmap = addLogoToQRCode(qrCodeBitmap, logo, logoPercent);
        } catch (WriterException e) {
            throw new RuntimeException(e);
        }

        return bitmap;
    }


    /**
     * 生成
     * 无白色边框
     * 二维码
     */
    public static Bitmap generateQRCodeWithoutMargin(String text, int width, int height) throws WriterException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.MARGIN, 0); // 设置边距为0

        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        int[] pixels = new int[width * height];

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (bitMatrix.get(x, y)) {
                    pixels[y * width + x] = Color.BLACK; // 黑色像素
                } else {
                    pixels[y * width + x] = Color.TRANSPARENT; // 透明像素,去除白边
                }
            }
        }

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);

        return bitmap;
    }

    /**
     * 给二维码
     * 添加logo
     */
    public static Bitmap addLogoToQRCode(Bitmap srcBitmap, Bitmap logoBitmap, float logoPercent) {
        // 计算Logo相对于二维码的尺寸
        int logoWidth = Math.round(srcBitmap.getWidth() * logoPercent);
        int logoHeight = Math.round(srcBitmap.getHeight() * logoPercent);

        // 确保Logo尺寸不会超过二维码尺寸
        if (logoWidth > srcBitmap.getWidth() || logoHeight > srcBitmap.getHeight()) {
            throw new IllegalArgumentException("Logo size is too large for the QR code.");
        }

        // 创建一个新的Bitmap来保存带Logo的二维码
        Bitmap resultBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
        Canvas canvas = new Canvas(resultBitmap);

        // 绘制原始二维码
        canvas.drawBitmap(srcBitmap, 0, 0, null);

        // 创建一个Matrix对象来缩放Logo
        Matrix matrix = new Matrix();
        matrix.postScale(logoWidth / (float) logoBitmap.getWidth(),
                logoHeight / (float) logoBitmap.getHeight());

        // 计算Logo应该放置的位置(中心)
        int xOffset = (srcBitmap.getWidth() - logoWidth) / 2;
        int yOffset = (srcBitmap.getHeight() - logoHeight) / 2;

        // 在二维码上绘制Logo
        canvas.drawBitmap(logoBitmap, xOffset, yOffset, null);

        return resultBitmap;
    }


}

二、方法说明

复制代码
   /**
     * 生成
     * 无白色边框
     * 二维码
     */
    public static Bitmap generateQRCodeWithoutMargin(String text, int width, int height) throws WriterException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.MARGIN, 0); // 设置边距为0

        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        int[] pixels = new int[width * height];

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (bitMatrix.get(x, y)) {
                    pixels[y * width + x] = Color.BLACK; // 黑色像素
                } else {
                    pixels[y * width + x] = Color.TRANSPARENT; // 透明像素,去除白边
                }
            }
        }

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);

        return bitmap;
    }

2、给二维码添加logo的方法

复制代码
   /**
     * 给二维码
     * 添加logo
     */
    public static Bitmap addLogoToQRCode(Bitmap srcBitmap, Bitmap logoBitmap, float logoPercent) {
        // 计算Logo相对于二维码的尺寸
        int logoWidth = Math.round(srcBitmap.getWidth() * logoPercent);
        int logoHeight = Math.round(srcBitmap.getHeight() * logoPercent);

        // 确保Logo尺寸不会超过二维码尺寸
        if (logoWidth > srcBitmap.getWidth() || logoHeight > srcBitmap.getHeight()) {
            throw new IllegalArgumentException("Logo size is too large for the QR code.");
        }

        // 创建一个新的Bitmap来保存带Logo的二维码
        Bitmap resultBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
        Canvas canvas = new Canvas(resultBitmap);

        // 绘制原始二维码
        canvas.drawBitmap(srcBitmap, 0, 0, null);

        // 创建一个Matrix对象来缩放Logo
        Matrix matrix = new Matrix();
        matrix.postScale(logoWidth / (float) logoBitmap.getWidth(),
                logoHeight / (float) logoBitmap.getHeight());

        // 计算Logo应该放置的位置(中心)
        int xOffset = (srcBitmap.getWidth() - logoWidth) / 2;
        int yOffset = (srcBitmap.getHeight() - logoHeight) / 2;

        // 在二维码上绘制Logo
        canvas.drawBitmap(logoBitmap, xOffset, yOffset, null);

        return resultBitmap;
    }

3、调用方式

复制代码
/**
     * @param content     字符串内容
     * @param size        位图宽&高(单位:px)
     * @param logo        二维码logo
     * @param logoPercent 二维码logo的占比 [0,1]
     * @return
     */
    public static Bitmap createQRCodeBitmapLogo(String content, int size, Bitmap logo, float logoPercent) {
        Bitmap qrCodeBitmap = null;
        Bitmap bitmap;
        try {
            // 不带logo二维码
            qrCodeBitmap = generateQRCodeWithoutMargin(content, size, size);
            // 带logo 二维码
            bitmap = addLogoToQRCode(qrCodeBitmap, logo, logoPercent);
        } catch (WriterException e) {
            throw new RuntimeException(e);
        }

        return bitmap;
    }

到此结束

相关推荐
DogDaoDao7 小时前
Android 硬件编码器参数完全指南:MediaCodec 深度解析
android·音视频·视频编解码·h264·硬编码·视频直播·mediacodec
JohnnyDeng948 小时前
Android 自定义 View:Canvas 绘图与事件分发深度解析
android
Android小码家11 小时前
Framework之Launcher小窗开发
android·framework·虚拟屏·小窗
赏金术士12 小时前
第七章:状态管理实战与架构总结
android·ui·kotlin·compose
颂love13 小时前
MySQL的执行流程
android·数据库·mysql
云起SAAS17 小时前
抖音小游戏源码 - 消消乐 | 含激励广告+成就系统 | 开箱即用商业级消除游戏模板
android·游戏·广告联盟·看激励广告联盟流量主·抖音小游戏源码 - 消消乐
大貔貅喝啤酒19 小时前
基于Windows下载安装Android Studio 3.3.2版本教程(2026详细图文版)
android·java·windows·android studio
程序员码歌19 小时前
OpenSpec 到 Superpowers:AI 编码从说清到做对
android·前端·人工智能
2501_9151063219 小时前
深入解析无源码iOS加固原理与方案,保护应用安全
android·安全·ios·小程序·uni-app·cocoa·iphone
黄林晴1 天前
重磅官宣:Android UI 开发正式进入 Compose-first 时代
android·google io