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      }

 

posted @ 2018-05-31 14:26  醉逍遥_001  阅读(479)  评论(0编辑  收藏  举报