`
zxmzfbdc
  • 浏览: 47031 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

zxing生成二维码添加图片和文字

 
阅读更多

 直接上代码,以后有时间再添加说明

二维码的基本信息,包括要二维码内包含的文字,嵌入的图片,加到二维码下边的文字

/**
 * 
 */
package com.tong.util.code;

import java.io.File;

/**
 * @author zxm
 *
 */
public class CodeModel {
	private String contents;
	private int width = 400;
	private int height = 400;
	private String format = "gif";
	private String character_set = "utf-8";
	private int fontSize = 12;
	private File logoFile;
	private float logoRatio = 0.20f;
	private String desc;
	private int whiteWidth;//白边的宽度
	private int[] bottomStart;//二维码最下边的开始坐标
	private int[] bottomEnd;//二维码最下边的结束坐标

	public String getContents() {
		return contents;
	}

	public void setContents(String contents) {
		this.contents = contents;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public String getFormat() {
		return format;
	}

	public void setFormat(String format) {
		this.format = format;
	}

	public String getCharacter_set() {
		return character_set;
	}

	public void setCharacter_set(String character_set) {
		this.character_set = character_set;
	}

	public int getFontSize() {
		return fontSize;
	}

	public void setFontSize(int fontSize) {
		this.fontSize = fontSize;
	}

	public File getLogoFile() {
		return logoFile;
	}

	public void setLogoFile(File logoFile) {
		this.logoFile = logoFile;
	}

	public float getLogoRatio() {
		return logoRatio;
	}

	public void setLogoRatio(float logoRatio) {
		this.logoRatio = logoRatio;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	public int getWhiteWidth() {
		return whiteWidth;
	}

	public void setWhiteWidth(int whiteWidth) {
		this.whiteWidth = whiteWidth;
	}

	public int[] getBottomStart() {
		return bottomStart;
	}

	public void setBottomStart(int[] bottomStart) {
		this.bottomStart = bottomStart;
	}

	public int[] getBottomEnd() {
		return bottomEnd;
	}

	public void setBottomEnd(int[] bottomEnd) {
		this.bottomEnd = bottomEnd;
	}
}

 生成二维码

/**
 * 
 */
package com.tong.util.code;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.springframework.util.StringUtils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 * @author zxm
 *
 */
public class CodeCreator {
	private static int BLACK = 0x000000;
	private static int WHITE = 0xFFFFFF;
	
	private BufferedImage createCodeImage(CodeModel info){
		String contents = info.getContents();
		int width = info.getWidth();
		int height = info.getHeight();
		Map<EncodeHintType, Object> hint = new HashMap<>();
		hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		hint.put(EncodeHintType.CHARACTER_SET, info.getCharacter_set());
		hint.put(EncodeHintType.MARGIN, 0);
		MultiFormatWriter writer = new MultiFormatWriter();
		BufferedImage img = null;
		try {
			BitMatrix bm = writer.encode(contents, BarcodeFormat.QR_CODE, width, height, hint);
			int[] locationTopLeft = bm.getTopLeftOnBit();
			int[] locationBottomRight = bm.getBottomRightOnBit();
			info.setBottomStart(new int[]{locationTopLeft[0], locationBottomRight[1]});
			info.setBottomEnd(locationBottomRight);
			int w = bm.getWidth();
			int h = bm.getHeight();
			img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
			for(int x=0;x<w;x++){
				for(int y=0;y<h;y++){
					img.setRGB(x, y, bm.get(x, y) ? BLACK : WHITE);
				}
			}
		} catch (WriterException e) {
			e.printStackTrace();
		}
		return img;
	}
	
	public void createCodeImage(CodeModel info, OutputStream output){
		BufferedImage bm = createCodeImage(info);
		File logoFile = info.getLogoFile();
		if(logoFile!=null && logoFile.exists()){
			try{
			BufferedImage logoImg = ImageIO.read(logoFile);
			int logoWidth = logoImg.getWidth();
			int logoHeight = logoImg.getHeight();
			int width = bm.getWidth();
			int height = bm.getHeight();
			float ratio = info.getLogoRatio();
			if(ratio>0){
				logoWidth = logoWidth>width*ratio ? (int)(width*ratio) : logoWidth;
				logoHeight = logoHeight>height*ratio ? (int)(height*ratio) : logoHeight;
			}
			int x = (width-logoWidth)/2;
			int y = (height-logoHeight)/2;
			Graphics g = bm.getGraphics();
			g.drawImage(logoImg, x, y, logoWidth, logoHeight, null);
			String desc = info.getDesc();
			//int whiteWidth = 8;
			if(!StringUtils.isEmpty(desc)){
				int whiteWidth = info.getHeight()-info.getBottomEnd()[1];
//				width = info.getBottomEnd()[0]-info.getBottomStart()[0];
//				height = info.getBottomEnd()[1]+1;
				Font font = new Font("黑体", Font.BOLD, info.getFontSize());
				int fontHeight = g.getFontMetrics(font).getHeight();
				//计算需要多少行
				int lineNum = 1;
				int currentLineLen = 0;
				for(int i=0;i<desc.length();i++){
					char c = desc.charAt(i);
					int charWidth = g.getFontMetrics(font).charWidth(c);
					if(currentLineLen+charWidth>width){
						lineNum++;
						currentLineLen = 0;
						continue;
					}
					currentLineLen += charWidth;
				}
				int totalFontHeight = fontHeight*lineNum;
				int wordTopMargin = 4;
				BufferedImage bm1 = new BufferedImage(width, height+totalFontHeight+wordTopMargin-whiteWidth, BufferedImage.TYPE_INT_RGB);
				Graphics g1 = bm1.getGraphics();
				if(totalFontHeight+wordTopMargin-whiteWidth>0){
				g1.setColor(Color.WHITE);
				g1.fillRect(0, height, width, totalFontHeight+wordTopMargin-whiteWidth);
				}
				g1.setColor(new Color(BLACK));
				g1.setFont(font);
				g1.drawImage(bm, 0, 0, null);
				width = info.getBottomEnd()[0]-info.getBottomStart()[0];
				height = info.getBottomEnd()[1]+1;
				currentLineLen = 0;
				int currentLineIndex = 0;
				int baseLo = g1.getFontMetrics().getAscent();
				for(int i=0;i<desc.length();i++){
					String c = desc.substring(i, i+1);
					int charWidth = g.getFontMetrics(font).stringWidth(c);
					if(currentLineLen+charWidth>width){
						currentLineIndex++;
						currentLineLen = 0;
						g1.drawString(c, currentLineLen + whiteWidth, height+baseLo+fontHeight*(currentLineIndex)+wordTopMargin);
						currentLineLen = charWidth;
						continue;
					}
					g1.drawString(c, currentLineLen+whiteWidth, height+baseLo+fontHeight*(currentLineIndex) + wordTopMargin);
					currentLineLen += charWidth;
				}
				g1.dispose();
				bm = bm1;
			}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		try{
			ImageIO.write(bm, StringUtils.isEmpty(info.getFormat()) ? info.getFormat() : info.getFormat(), output);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public void createCodeImage(CodeModel info, File file){
		File parent = file.getParentFile();
		if(!parent.exists())parent.mkdirs();
		OutputStream output = null;
		try{
			output = new BufferedOutputStream(new FileOutputStream(file));
			createCodeImage(info, output);
			output.flush();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				output.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void createCodeImage(CodeModel info, String filePath){
		createCodeImage(info, new File(filePath));
	}
}

 二维码读取

/**
 * 
 */
package com.tong.util.code;

import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;

/**
 * @author zxm
 *
 */
public class CodeDecoder {
	public String decode(InputStream input){
		Map<DecodeHintType, Object> hint = new HashMap<DecodeHintType, Object>();
		hint.put(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE);
		String result = "";
		try{
		BufferedImage img = ImageIO.read(input);
		int[] pixels = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth());
		LuminanceSource source = new RGBLuminanceSource(img.getWidth(), img.getHeight(), pixels);
		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
		QRCodeReader reader = new QRCodeReader();
		Result r = reader.decode(bitmap, hint);
		result = r.getText();
		}catch(Exception e){
			result="读取错误";
		}
		return result;
	}
}

 

测试代码

 

/**
 * 
 */
package com.tong.util;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.tong.util.code.CodeCreator;
import com.tong.util.code.CodeDecoder;
import com.tong.util.code.CodeModel;

/**
 * @author zxm
 *
 */
public class QRCodeMain{
	private static void encode() {
		CodeCreator creator = new CodeCreator();
		CodeModel info = new CodeModel();
		info.setWidth(400);
		info.setHeight(400);
		info.setFontSize(24);
		info.setContents("<a href='http://www.sohu.com'>人生就是拼搏</a>");
		//info.setContents("http://www.sohu.com");
		info.setContents("万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新\n万水千山只等闲\n小荷才楼尖尖角\n谁家新燕啄春泥\n无边光景一时新");
		info.setLogoFile(new File("D:/workspaces/workspace1/tong3/WebContent/img/girl3.jpg"));
		info.setDesc("你怎么会知道我的苦,我是一页孤舟,漂流在尘世中asdfsaf33333abCD1234567890");
		//info.setLogoDesc("一叶浮萍归大海,adsasfbhtjg人生何处不相逢");
		//info.setLogoDesc("一叶浮萍");
		creator.createCodeImage(info, "D:/2Dcode/dest." + info.getFormat());
	}
	
	static public void decode(InputStream input){
		CodeDecoder decoder = new CodeDecoder();
		String result = decoder.decode(input);
		System.out.println(result);
	}
	
	public static void main(String[] args) throws Exception{
		encode();
		//decode(new FileInputStream(new File("D:/2Dcode/dest.gif")));
	}
}
 

 

 

  • 大小: 21.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics