java实现二维码的生成

https://blog.csdn.net/jam_fanatic/article/details/82818857

失效二维码方案:

1.生成二维码并把值设置为中转地址(某随机字符串,如www.a.com/qr/1111)
2.在redis中放入key: 1111, value: 真实二维码跳转地址,expire: 你想要的过期时间

用户扫码后,进入中转地址,在redis中检查是否存在这个key,如果存在则redirect到value,不存在则跳转到统一的过期页面。

注:Barcode编码格式介绍:https://blog.csdn.net/liudongdong19/article/details/80147404

      MIME 参考手册:https://www.w3school.com.cn/media/media_mimeref.asp    也可以参考tomcat下conf文件下的web.xml的配置  

     像素说明:https://blog.csdn.net/elimago/article/details/5391582     

比如data:image/png;base64,中png对应的是image/png

<mime-mapping>
        <extension>png</extension>
        <mime-type>image/png</mime-type>
    </mime-mapping>

使用base64生成二维码:

maven依赖:

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>2.2</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>2.2</version>
</dependency>
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.haierubic.cloud.datatools.dto.TransferTypeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.HashMap;

import static com.google.zxing.client.j2se.MatrixToImageConfig.BLACK;
import static com.google.zxing.client.j2se.MatrixToImageConfig.WHITE;

public class QrCodeUtils {
    private static final Logger logger = LoggerFactory.getLogger(QrCodeUtils.class);

    /**
     * 设置编码方式,默认是“ISO-8859-1”编码方式
     * 错误修正容量
     * L 1 水平 7%的字码可被修正
     * M 0 水平 15%的字码可被修正
     * Q 3 水平 25%的字码可被修正
     * H 2 水平 30%的字码可被修正
     */
    public static HashMap hints = new HashMap() {
        {
            put(EncodeHintType.CHARACTER_SET, "utf-8");
            put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            put(EncodeHintType.MARGIN, 0);
        }
    };

    public static String creatRrCode(String content, int width, int height, String imgType, String imgValue, String icon, TransferTypeEnum iconWay, boolean hasIcon) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            String binary = null;
            /* *
             * contents:条形码/二维码内容
             *  format:编码类型,如 条形码,二维码 等;BarcodeFormat.QR_CODE为二维条码编码格式
             *  width:码的宽度,单位为像素
             *  height:码的高度,单位为像素
             *  hints:码内容的编码类型
             *  BarcodeFormat:枚举该程序包已知的条形码格式,即创建何种码,如 1 维的条形码,2 维的二维码 等
             *  BitMatrix:位(比特)矩阵或叫2D矩阵,也就是需要的二维码*/

            BitMatrix bitMatrix = new MultiFormatWriter().encode(
                    content, BarcodeFormat.QR_CODE, width, height, hints);
            BufferedImage image = toBufferedImage(bitMatrix);
            //二维码中添加图片
            if (hasIcon) {
                if (TransferTypeEnum.BASE64STRING == iconWay) {
                    BASE64Decoder decoder = new BASE64Decoder();
                    byte[] bytes1 = decoder.decodeBuffer(icon);
                    ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
                    //生成带base64 icon的二维码 base64
                    insertImage(image, null, bais, true);
                    bais.close();
                } else {
                    //生成带URL icon的二维码 base64
                    URL url = new URL(icon);
                    insertImage(image, url, null, false);
                }
            }
            //转换成type格式的IO流
            ImageIO.write(image, imgType, out);
            byte[] bytes = out.toByteArray();
            // 2、将字节数组转为二进制
            BASE64Encoder encoder = new BASE64Encoder();
            String binaryTemp = encoder.encodeBuffer(bytes).trim();
            binary = binaryTemp.replaceAll("\n", "").replaceAll("\r", "");
            //获取mime
            return "data:" + imgValue + ";base64," + binary;
        } catch (Exception e) {
            logger.error("Failed to generate QR code!!! content:{}  icon:{}", content, icon, e);
            throw e;
        } finally {
            out.close();
        }
    }

    /**
     * icon传入方式为url
     *
     * @param source
     * @param url
     * @throws Exception
     */
    public static void insertImage(BufferedImage source, URL url, ByteArrayInputStream bais, boolean isBase64) throws Exception {
        try {
            Image src = null;
            if (isBase64) {
                src = ImageIO.read(bais);
            } else {
                src = ImageIO.read(url);
            }
            int width = source.getWidth();
            int height = source.getHeight();
            // 插入icon
            Graphics2D graph = source.createGraphics();
            int x = width * 7 / 20;
            int y = height * 7 / 20;
            int iconWidth = width - 2 * x;
            int iconHeigth = height - 2 * x;
            graph.drawImage(src, x, y, iconWidth, iconHeigth, null);
            graph.dispose();
        } catch (Exception e) {
            logger.error("insertImage error!!!", e);
            throw e;
        }
    }

    /**
     * 不去除白边
     * image流数据处理
     * 0xFFFFFFFF 白色像素 ;0xFF000000 黑色像素
     * 像素生成模式 RGB
     */
    public static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        return image;
    }

    /**
     * 去除白边
     * 读取二维码区域重新生成一个BitMatrix
     */
    public static BufferedImage deleteWhite(BitMatrix matrix) {
        //排除0bit
        int[] rec = matrix.getEnclosingRectangle();
        int resWidth = rec[2] + 1;
        int resHeight = rec[3] + 1;
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
        resMatrix.clear();
        for (int i = 0; i < resWidth; i++) {
            for (int j = 0; j < resHeight; j++) {
                if (matrix.get(i + rec[0], j + rec[1])) {
                    resMatrix.set(i, j);
                }
            }
        }
        int width = resMatrix.getWidth();
        int height = resMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, resMatrix.get(x, y) ? BLACK
                        : WHITE);
            }
        }
        return image;
    }
//图片转base64
public static String imageToBase64(String impagePath) throws Exception{
    File file=new File(impagePath);
    BufferedImage bufferedImage=null;
    try {
        //图片转base64
        bufferedImage=ImageIO.read(file) ;
        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
        ImageIO.write(bufferedImage,"jpg",outputStream);
        byte[] bytes=outputStream.toByteArray();
        // 2、将字节数组转为二进制
        BASE64Encoder encoder = new BASE64Encoder();
        //BASE64Encoder.encodeBuffer 对字符串进行加密
        String base64String = encoder.encodeBuffer(bytes).trim();
        base64String.replaceAll("\n", "").replaceAll("\r", "");
        System.out.println("data:image/jpeg;base64,"+base64String);
        //return "data:image/jpeg;base64,"+base64String;
        return base64String;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }catch (IOException e){
        e.printStackTrace();
    }
    return null;
}

//base64转图片
public static void base64ToImage()throws Exception {
   String base64String=imageToBase64("D://0/dog.jpg");
        BASE64Decoder decoder=new BASE64Decoder();
        byte[] bytes1 = decoder.decodeBuffer(base64String);
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
        BufferedImage bi1 = ImageIO.read(bais);
        File f1 = new File("d://out.jpg");
        ImageIO.write(bi1, "jpg", f1);
}
}
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值