QR码创建过程解析

去网上找了很多关于QR码创建的代码,结果都没有很满意的解释,于是就拿了一段网上出现概率比较高的代码进行分析。有什么不好的地方请及时指正!

public class QRCodeEncoder {

    /**
     * 编码字符串内容到目标new File(test.png)中
     * @param encodeddata
     * @param destFile
     * @throws IOException
     */
    //字符串->用gbk编码将字符串表示出来存到byte[]数组中->用Qrcode中的calQrcode(d)将转换后的编码变为boolean形式->根据boolean数组值在图片中画出二维码
    public static void qrCodeEncode(String encodeddata,File destFile) throws IOException{
        Qrcode qrcode = new Qrcode();
        //错误修正容量   
        //L水平   7%的字码可被修正  
        //M水平   15%的字码可被修正  
        //Q水平   25%的字码可被修正  
        //H水平   30%的字码可被修正  
        //QR码有容错能力,QR码图形如果有破损,仍然可以被机器读取内容,最高可以到7%~30%面积破损仍可被读取。  
        //相对而言,容错率愈高,QR码图形面积愈大。所以一般折衷使用15%容错能力。
        qrcode.setQrcodeErrorCorrect('M');//设置错误修正容量
        qrcode.setQrcodeEncodeMode('B');//设置编码方式
        qrcode.setQrcodeVersion(7);//设置版本号
        byte[] d = encodeddata.getBytes("utf-8");//得到指定编码的字节数组    字符串--->字节数组 ,得到的是字符编码.注意这儿用utf-8,不要用其他的,否则用微信扫出来是乱码。
        BufferedImage bi = new BufferedImage(139, 139,BufferedImage.TYPE_INT_RGB);//新建一个宽为139,高为139,图片类型为BufferedImage.TYPE_INT_RGB的BufferedImage
        // createGraphics
        Graphics2D g = bi.createGraphics();
        // set background
        g.setBackground(Color.WHITE);
        g.clearRect(0, 0, 139, 139);
        //设置二维码图片颜色
        g.setColor(Color.BLACK);

        //将数据转换为boolean值,若为true,则在相应的位置填充
        if (d.length > 0 && d.length < 123) {
            boolean[][] b = qrcode.calQrcode(d);//快速响应QR码,将byte[]数组转换为bollean[][],便于后期二维码图片实现            
            for (int i = 0; i < b.length; i++) {
                for (int j = 0; j < b.length; j++) {
                    //System.out.print(b[j][i]+"~");
                    if (b[j][i]) {
                        g.fillRect(j * 3 + 2, i * 3 + 2, 3, 3);
                    }
                }
            }
        }
        g.dispose();
        bi.flush();

        ImageIO.write(bi, "png", destFile);//图片存入对应位置,注意,destFile是产生的图片名称
        System.out.println("Input Encoded data is:"+encodeddata);
    } 
    public static void main(String[] args) throws IOException {
        QRCodeEncoder q = new QRCodeEncoder();
        q.qrCodeEncode("宝宝第一次写博客啦", new File("test.png"));
    }
}

宝宝将对以上的一些代码进行分析

1.byte[] d = encodeddata.getBytes("utf-8");

对这儿不是很清楚的,可以参考String(byte[] bytes, Charset charset) 和 getBytes() 使用

2.BufferedImage bi = new BufferedImage(139, 139, BufferedImage.TYPE_INT_RGB);

这儿请看源码

/**
     * Constructs a <code>BufferedImage</code> of one of the predefined
     * image types.  The <code>ColorSpace</code> for the image is the
     * default sRGB space.
     * @param width     width of the created image
     * @param height    height of the created image
     * @param imageType type of the created image
     * @see ColorSpace
     * @see #TYPE_INT_RGB
     * @see #TYPE_INT_ARGB
     * @see #TYPE_INT_ARGB_PRE
     * @see #TYPE_INT_BGR
     * @see #TYPE_3BYTE_BGR
     * @see #TYPE_4BYTE_ABGR
     * @see #TYPE_4BYTE_ABGR_PRE
     * @see #TYPE_BYTE_GRAY
     * @see #TYPE_USHORT_GRAY
     * @see #TYPE_BYTE_BINARY
     * @see #TYPE_BYTE_INDEXED
     * @see #TYPE_USHORT_565_RGB
     * @see #TYPE_USHORT_555_RGB
     */
    public BufferedImage(int width,
                         int height,
                         int imageType) {
        switch (imageType) {
        case TYPE_INT_RGB:
            {
                colorModel = new DirectColorModel(24,                                                0x00ff0000,   // Red                                                  0x0000ff00,   // Green                                                  0x000000ff,   // Blue                                                  0x0           // Alpha                                                  );
                raster = colorModel.createCompatibleWritableRaster(width,                                                                 height);
                }
        break;
        case TYPE_INT_ARGB:
            {
                colorModel = ColorModel.getRGBdefault();
                raster = colorModel.createCompatibleWritableRaster(width,                                                               height);
            }
        break;
        case TYPE_INT_ARGB_PRE:
            {
                colorModel = new
                    DirectColorModel(                                   ColorSpace.getInstance(ColorSpace.CS_sRGB),
                                     32,
                                     0x00ff0000,// Red
                                     0x0000ff00,// Green
                                     0x000000ff,// Blue
                                     0xff000000,// Alpha
                                     true,       // Alpha Premultiplied
                                     DataBuffer.TYPE_INT
                                     );
                raster = colorModel.createCompatibleWritableRaster(width,
                                                                   height);
            }
        break;
        case TYPE_INT_BGR:
            {
                colorModel = new DirectColorModel(24,
                0x000000ff,   // Red                                               
                0x00ff0000    // Blue                                                  );
                raster = colorModel.createCompatibleWritableRaster(width,                                                          height);
                            }
        break;
        case TYPE_3BYTE_BGR:
            {
                ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
                int[] nBits = {8, 8, 8};
                int[] bOffs = {2, 1, 0};
                colorModel = new ComponentColorModel(cs, nBits, false, false,
                                                     Transparency.OPAQUE,
                                                     DataBuffer.TYPE_BYTE);
                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,                                                       width, height,                                                        width*3, 3,                                                        bOffs, null);            }
        break;
        case TYPE_4BYTE_ABGR:
            {                ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
                int[] nBits = {8, 8, 8, 8};
                int[] bOffs = {3, 2, 1, 0};
                colorModel = new ComponentColorModel(cs, nBits, true, false,                                                     Transparency.TRANSLUCENT,                              DataBuffer.TYPE_BYTE);                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
                                                        width, height,
                                                        width*4, 4,
                                                        bOffs, null);
            }
        break;

        case TYPE_4BYTE_ABGR_PRE:
            {
                ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
                int[] nBits = {8, 8, 8, 8};
                int[] bOffs = {3, 2, 1, 0};
                colorModel = new ComponentColorModel(cs, nBits, true, true,
                                                     Transparency.TRANSLUCENT,
                                                     DataBuffer.TYPE_BYTE);
                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
                                                        width, height,
                                                        width*4, 4,
                                                        bOffs, null);
            }
        break;

        case TYPE_BYTE_GRAY:
            {
                ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
                int[] nBits = {8};
                colorModel = new ComponentColorModel(cs, nBits, false, true,
                                                     Transparency.OPAQUE,
                                                     DataBuffer.TYPE_BYTE);
                raster = colorModel.createCompatibleWritableRaster(width,
                                                                   height);
            }
        break;

        case TYPE_USHORT_GRAY:
            {
                ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
                int[] nBits = {16};
                colorModel = new ComponentColorModel(cs, nBits, false, true,
                                                     Transparency.OPAQUE,
                                                     DataBuffer.TYPE_USHORT);
                raster = colorModel.createCompatibleWritableRaster(width,
                                                                   height);
            }
        break;

        case TYPE_BYTE_BINARY:
            {
                byte[] arr = {(byte)0, (byte)0xff};

                colorModel = new IndexColorModel(1, 2, arr, arr, arr);
                raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE,
                                                   width, height, 1, 1, null);
            }
        break;

        case TYPE_BYTE_INDEXED:
            {
                // Create a 6x6x6 color cube
                int[] cmap = new int[256];
                int i=0;
                for (int r=0; r < 256; r += 51) {
                    for (int g=0; g < 256; g += 51) {
                        for (int b=0; b < 256; b += 51) {
                            cmap[i++] = (r<<16)|(g<<8)|b;
                        }
                    }
                }
                // And populate the rest of the cmap with gray values
                int grayIncr = 256/(256-i);

                // The gray ramp will be between 18 and 252
                int gray = grayIncr*3;
                for (; i < 256; i++) {
                    cmap[i] = (gray<<16)|(gray<<8)|gray;
                    gray += grayIncr;
                }

                colorModel = new IndexColorModel(8, 256, cmap, 0, false, -1,
                                                 DataBuffer.TYPE_BYTE);
                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
                                                      width, height, 1, null);
            }
        break;

        case TYPE_USHORT_565_RGB:
            {
                colorModel = new DirectColorModel(16,
                                                  DCM_565_RED_MASK,
                                                  DCM_565_GRN_MASK,
                                                  DCM_565_BLU_MASK
                                                  );
                raster = colorModel.createCompatibleWritableRaster(width,
                                                                   height);
            }
            break;

        case TYPE_USHORT_555_RGB:
            {
                colorModel = new DirectColorModel(15,
                                                  DCM_555_RED_MASK,
                                                  DCM_555_GRN_MASK,
                                                  DCM_555_BLU_MASK
                                                  );
                raster = colorModel.createCompatibleWritableRaster(width,
                                                                   height);
            }
            break;

        default:
            throw new IllegalArgumentException ("Unknown image type " +
                                                imageType);
        }

        this.imageType = imageType;
    }
 3.       if (d.length > 0 && d.length < 123) {
            boolean[][] b = qrcode.calQrcode(d);//快速响应QR码,将byte[]数组转换为bollean[][],便于后期二维码图片实现            
            for (int i = 0; i < b.length; i++) {
                for (int j = 0; j < b.length; j++) {
                    //System.out.print(b[j][i]+"~");
                    if (b[j][i]) {
                        g.fillRect(j * 3 + 2, i * 3 + 2, 3, 3);
                    }
                }
            }
        }

这儿是在之前byte[] d = encodeddata.getBytes(“utf-8”)的基础上,将获取的byte[] d通过boolean[][] b = qrcode.calQrcode(d)转变为boolean,即所有的值变为true或者false。举个例子,原来有encodeddata=“a”,经过byte[] d = encodeddata.getBytes(“utf-8”)后,a转换成了“97”,再经过boolean[][] b = qrcode.calQrcode(d),则97又转换成了true和false组成的布尔数组。在这个基础上实现二维码图片。
即String->byte[]->boolean[][]->二维码图片。
最后附上本宝宝做好的二维码给大家。
生成好的二维码
图片路径

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值