java - 小程序二维码中间的logo占整个二维码的比例计算

使用java替换小程序二维码中间的logo时候,比较烦恼的事是需要将二维码中间的logo替换掉,画上自己的logo。

下边是我计算之后的结果,这种计算方式会根据二维码的尺寸,动态的改变logo的尺寸。希望对你们有帮助。

    /**
     * 合并小程序二维码和头像
     *
     * @param qrCode     二维码
     * @param avatarUrl  头像
     * @return
     */
    public BufferedImage mergeImage(BufferedImage qrCode, String avatarUrl) {

        // 将头像转为圆角
        BufferedImage avatarImage = copeImage(avatarUrl);

        //创建Graphics2D绘图
        Graphics2D graphics = qrCode.createGraphics();

        // 设置抗锯齿的属性
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        int qrWidth = qrCode.getWidth();// 二维码宽度
        int qrHeight = qrCode.getHeight();// 二维码高度
        int logoQrWidth = (int) (qrWidth / 2.2); // 组合之后logo的宽度(占二维码的1/2.2)
        int logoQrHeight = (int) (qrHeight / 2.2);// 组合之后logo的高度

        // 左边距、上边距、宽度、高度。覆盖原始图片中间的logo
        graphics.drawImage(
                avatarImage,
                (qrWidth - logoQrWidth) / 2,
                (qrHeight - logoQrHeight) / 2,
                logoQrWidth,
                logoQrHeight,
                null);

        //关闭
        graphics.dispose();

        return qrCode;
    }

上边是合并图片的方式。

下边是把图片裁剪成圆角的方式。

    /**
     * 将图片处理成圆角
     *
     * @return
     */
    public BufferedImage copeImage(String avatarUrl) {

        // 从链接中获取图片
        BufferedImage avatarImage;
        try {
            avatarImage = ImageIO.read(new URL(avatarUrl));
            int width = avatarImage.getWidth();
            int height = avatarImage.getHeight();
            // 透明底的图片
            BufferedImage formatAvatarImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
            Graphics2D graphics = formatAvatarImage.createGraphics();
            // 把图片切成一个圆
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            // 留一个像素的空白区域,这个很重要,画圆的时候把这个覆盖
            int border = 1;
            // 图片是一个圆型
            Ellipse2D.Double shape = new Ellipse2D.Double(border, border, width - border * 2, width - border * 2);
            // 需要保留的区域
            graphics.setClip(shape);
            graphics.drawImage(avatarImage, border, border, width - border * 2, width - border * 2, null);
            graphics.dispose();

            // 在圆图外面再画一个圆
            // 新创建一个graphics,这样画的圆不会有锯齿
            graphics = formatAvatarImage.createGraphics();
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            int border1 = 3;
            //画笔是4.5个像素,BasicStroke的使用可以查看下面的参考文档
            //使画笔时基本会像外延伸一定像素,具体可以自己使用的时候测试
            Stroke s = new BasicStroke(4.5F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
            graphics.setStroke(s);
            graphics.setColor(Color.WHITE);
            graphics.drawOval(border1, border1, width - border1 * 2, width - border1 * 2);
            graphics.dispose();

            return formatAvatarImage;
        } catch (Exception e) {
            logger.error("将头像变为圆角异常", e);
        }

        return null;
    }

成品看下图:

java - 小程序二维码中间的logo占整个二维码的比例计算