zoukankan      html  css  js  c++  java
  • java利用zxing生成二维码

    首先需要相应jar包

    maven依赖添加

    <dependency>
    		    <groupId>com.google.zxing</groupId>
    		    <artifactId>core</artifactId>
    		    <version>3.3.0</version>
    		</dependency>
    		<dependency>
    		    <groupId>com.google.zxing</groupId>
    		    <artifactId>javase</artifactId>
    		    <version>3.3.0</version>
    		</dependency>

    直接写在controller里面的二维码生成

    private static final int WIDTH = 60;
    	   
        private static final int HEIGHT = 60;
    
    	private static final String CHARSET = "UTF-8";
        
    	private static final String FORMAT_NAME = "JPG";
    	@GetMapping(value = "/showQRCode/{id}")
    	public void showQRCode(@PathVariable("id") String id,HttpServletResponse resp) throws Exception {
    		xxxSignAddress xxxSignAddress = districtService.selectRegionById(id);
    		String content = xxxSignAddress.toString();
    		Map<EncodeHintType,Object> config = new HashMap<>();
    		config.put(EncodeHintType.CHARACTER_SET,CHARSET);//字符编码
    		config.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//纠错等级
    		config.put(EncodeHintType.MARGIN, 0);
    		BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,WIDTH,HEIGHT,config);
    		Path file = new File("g:/QRCode"+File.separator+IdGen.uuid()+".png").toPath();
    		MatrixToImageWriter.writeToPath(bitMatrix,FORMAT_NAME,file);
    		System.out.println("二维码生成完毕,已经保存至相关路径中。");
    //		下面是将其path保存到数据库,并以流的形式返回给前端,这里需要HttpServletResponse的相应输出流
    		File filePath=new File(file.toString());
    		String path=filePath.getAbsolutePath();
    		xxxSignAddress gsa = new xxxSignAddress();
    		gsa.setId(id);
    		gsa.setName(xxxSignAddress.getName());
    		gsa.setCustomer(xxxSignAddress.getCustomer());
    		gsa.setPath(path);
    		districtService.savePath(gsa);
    		OutputStream os = resp.getOutputStream();//取得输出流
    		MatrixToImageWriter.writeToStream(bitMatrix, FORMAT_NAME, os);//写入文件刷新
    		}

            然后优化提出来一个二维码生成的工具类,和controller,这里考虑了既要将二维码显示在前端,也要将二维码保存下来,并将路径保存到相应数据库中

    工具类如下:

    package com.xxx.cloud.common.utils;
    
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.nio.file.Path;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    
    import org.springframework.core.io.FileSystemResource;
    import org.springframework.core.io.InputStreamResource;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.NotFoundException;
    import com.google.zxing.Result;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    public class QRCodeUtil {
    	
    	private static final int WIDTH = 60;
       
        private static final int HEIGHT = 60;
    
    	private static final String CHARSET = "UTF-8";
        
    	public static final String FORMAT_NAME = "JPG";
    	
    	
    	public static Map<String,Object> createQRCode(String content) throws Exception {
    	Map<EncodeHintType,Object> config = new HashMap<>();
    	config.put(EncodeHintType.CHARACTER_SET,CHARSET);//字符编码
    	config.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//纠错等级
    	config.put(EncodeHintType.MARGIN, 0);
    	BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,WIDTH,HEIGHT,config);
    	Path file = new File("g:/QRCode"+File.separator+IdGen.uuid()+".png").toPath();
    	MatrixToImageWriter.writeToPath(bitMatrix,FORMAT_NAME,file);
    	System.out.println("二维码生成完毕,已经保存至相关路径中。");
    	File filePath=new File(file.toString());
    	String path=filePath.getAbsolutePath();
    	Map<String,Object> data = new HashMap<String,Object>();
    	data.put("qrcode", bitMatrix);
    	data.put("path", path);
    	return data;
    }
    }

    如上代码为了在controller中保存路径到数据库,同时为了将二维码刷新到前端,故而将路径和二维码生成的图像通过map返回来,在controller中取出并作适当类型转换,然后就可以实现。

    controller代码如下:

    @GetMapping(value = "/showQRCode/{id}")
    	public void showQRCode(@PathVariable("id") String id,HttpServletResponse resp) throws Exception {
    		xxxSignAddress xxxSignAddress = districtService.selectRegionById(id);
    		String content = xxxSignAddress.toString();
    		Map<String,Object> data = QRCodeUtil.createQRCode(content);
    		String path = (String) data.get("path");
    		BitMatrix bitMatrix = (BitMatrix) data.get("qrcode");
    		xxxSignAddress gsa = new xxxSignAddress();
    		gsa.setId(id);
    		gsa.setName(xxxSignAddress.getName());
    		gsa.setCustomer(xxxSignAddress.getCustomer());
    		gsa.setPath(path);
    		districtService.savePath(gsa);
    		OutputStream os = resp.getOutputStream();//取得输出流
    		MatrixToImageWriter.writeToStream(bitMatrix, QRCodeUtil.FORMAT_NAME, os);//写入文件刷新
    		}

    测试均ok,如下

    解析二维码的代码也放上

    //	解析二维码
        public static void readQRCode(File file){
        	
        	try {
        		MultiFormatReader formatReader = new MultiFormatReader();
    			BufferedImage image = ImageIO.read(file);
    			BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image)));
    			HashMap hints = new HashMap();
    			hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
    			Result result = formatReader.decode(binaryBitmap, hints);
    			} catch (NotFoundException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
        }	
    再次优化的返回Base64字节码和二维码url的代码
     1     @GetMapping(value = "/showQRCode/{id}")
     2     public ResponseObj showQRCode(@PathVariable("id") String id, HttpServletResponse resp) throws Exception {
     3         ResponseObj response = new ResponseObj();
     4         response.setMessage("二维码生成并显示成功");
     5         response.setStatus(Defined.STATUS_SUCCESS);
     6         xxxSignAddress xxxSignAddress = districtService.selectRegionById(id);
     7         String content ="signAddressId:"+xxxSignAddress.getId();
     8         Map<String, Object> dataInfo = QRCodeUtil.createQRCode(content);
     9         BitMatrix bitMatrix = (BitMatrix) dataInfo.get("qrcode");
    10         // 输出流转换为输入流,并上传二维码
    11         ByteArrayOutputStream bos = new ByteArrayOutputStream();
    12         MatrixToImageWriter.writeToStream(bitMatrix, QRCodeUtil.FORMAT_NAME, bos);// 写入文件刷新
    13         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    14         String path = upload(bis, "png");
    15         xxxSignAddress gsa = new xxxSignAddress();
    16         gsa.setId(id);
    17         gsa.setUpdateBy(getCurrentUser().getAccount().getUserId());
    18         gsa.setUpdateTime(DateUtil.getNowTimestamp());
    19         gsa.setPath(path);
    20         districtService.savePath(gsa);
    21         ByteArrayInputStream is = new ByteArrayInputStream(bos.toByteArray());
    22         int i = is.available(); // 得到文件大小      
    23         byte bytes[] = new byte[i];      
    24         is.read(bytes); // 读数据      
    25         is.close();      
    26       //对字节数组Base64编码  
    27         BASE64Encoder encoder = new BASE64Encoder();  
    28         String QRStr = encoder.encode(bytes);//返回Base64编码过的字节数组字符串  
    29         Map<String,Object> data = new HashMap<String,Object>();
    30         data.put("QRStr", QRStr);
    31         data.put("QRUrl", aliConstants.aliyunHostOuter+"/"+path);
    32         response.setData(data);
    33         return response;
    34     }

    运行结果

    生成含logo的二维码

    补充代码

    private static final int BLACK = 0xFF000000;
    private static final int WHITE = 0xFFFFFFFF;

     1  public static BufferedImage createQRCodeWithLogo(String data, String charset, Hashtable<EncodeHintType, ?> hint,
     2             int width, int height, File logoFile) {
     3         try {
     4             BufferedImage qrcode = createQRCodeLogo(data);
     5             BufferedImage logo = ImageIO.read(logoFile);
     6             int deltaHeight = height - logo.getHeight();
     7             int deltaWidth = width - logo.getWidth();
     8  
     9             BufferedImage combined = new BufferedImage(height, width, BufferedImage.TYPE_INT_ARGB);
    10             Graphics2D g = (Graphics2D) combined.getGraphics();
    11             g.drawImage(qrcode, 0, 0, null);
    12             g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
    13             g.drawImage(logo, (int) Math.round(deltaWidth / 2), (int) Math.round(deltaHeight / 2), null);
    14  
    15             return combined;
    16         } catch (IOException e) {
    17             throw new RuntimeException(e.getMessage(), e);
    18         } catch (Exception e) {
    19             throw new RuntimeException(e.getMessage(), e);
    20         }
    21     }
    22     
    23     public static BufferedImage createQRCodeLogo(String data) throws Exception {
    24     Map<EncodeHintType,Object> config = new HashMap<>();
    25     config.put(EncodeHintType.CHARACTER_SET,CHARSET);//字符编码
    26     config.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//纠错等级
    27     config.put(EncodeHintType.MARGIN, 0);
    28     BitMatrix bitMatrix = new MultiFormatWriter().encode(data, BarcodeFormat.QR_CODE,WIDTH,HEIGHT,config);
    29     return toBufferedImage(bitMatrix);
    30 }
    31     
    32     
    33     
    34     public static BufferedImage toBufferedImage(BitMatrix matrix) {
    35         int width = matrix.getWidth();
    36         int height = matrix.getHeight();
    37         BufferedImage image = new BufferedImage(width, height,
    38                 BufferedImage.TYPE_INT_RGB);
    39         for (int x = 0; x < width; x++) {
    40             for (int y = 0; y < height; y++) {
    41                 image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
    42             }
    43         }
    44         return image;
    45     }
    46     /* public static void main(String[] args) throws IOException, NotFoundException{
    47             String data = "http://www.baidu.com";
    48             File logoFile = new File("G:/打印二维码logo.png");
    49             Hashtable<EncodeHintType,Object> config = new Hashtable<>();
    50             config.put(EncodeHintType.CHARACTER_SET,CHARSET);//字符编码
    51             config.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//纠错等级
    52             config.put(EncodeHintType.MARGIN, 0);
    53             BufferedImage image = QRCodeUtil.createQRCodeWithLogo(data,CHARSET, config,WIDTH,HEIGHT,logoFile);
    54             ImageIO.write(image, "png", new File("g:/xxx_zxing_logo.png"));
    55         }*/
    56      
    57      public static Map<String,Object> getQRCodeWithLogo(File logoFile,String content){
    58             Hashtable<EncodeHintType,Object> config = new Hashtable<>();
    59             config.put(EncodeHintType.CHARACTER_SET,CHARSET);//字符编码
    60             config.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//纠错等级
    61             config.put(EncodeHintType.MARGIN, 0);
    62             BufferedImage image = QRCodeUtil.createQRCodeWithLogo(content,CHARSET, config,WIDTH,HEIGHT,logoFile);
    63             Map<String,Object> data = new HashMap<String,Object>();
    64             data.put("qrcode", image);
    65             return data;
    66      }
  • 相关阅读:
    BIOS详解:什么是BIOS ?BIOS的作用?CMOS及其与BIOS的关系?
    随机数不随机
    解决hexo神烦的DTraceProviderBindings MODULE_NOT_FOUND
    保护模式特权级别DPL,RPL,CPL 之间的联系和区别
    Linux内核 hlist_head/hlist_node结构解析
    x86中的页表结构和页表项格式
    Linux下/proc目录简介
    bdev文件系统
    X86 IO端口和MMIO
    Mac OS Alfred 2 tips
  • 原文地址:https://www.cnblogs.com/xiaoyao-001/p/9184790.html
Copyright © 2011-2022 走看看