使用zxing生成嵌图片的二维码【java】

来源:互联网 发布:状态数据采集分析报告 编辑:程序博客网 时间:2024/05/20 21:19

涉及两方面的知识:

1.QR code的基础,参见大牛的作品http://coolshell.cn/articles/10590.html

2.java图形库image、Graphics2D等


基本思路是先使用zxing生成的二维码图片,然后读取图片,在其中插入图标,然后整个输出图片。

网上还看到另外一种做法,先生成二维码图片,然后把图标直接覆盖在二维码上,这样会丢失一部分数据,但是由于二维码的纠错能力,扫描器能够把丢失的信息找回来。


废话不说,直接上代码:

/** *  */package barcode;import java.awt.Color;import java.awt.Graphics2D;import java.awt.Image;import java.awt.geom.AffineTransform;import java.awt.image.AffineTransformOp;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;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;/** * @author lichunxi *  */public class BarcodeFactory {// 图片宽度的一般private static final int IMAGE_WIDTH = 80;private static final int IMAGE_HEIGHT = 80;private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;private static final int FRAME_WIDTH = 2;// 二维码写码器private static MultiFormatWriter mutiWriter = new MultiFormatWriter();public static void encode(String content, int width, int height,String srcImagePath, String destImagePath) {try {ImageIO.write(genBarcode(content, width, height, srcImagePath),"jpg", new File(destImagePath));} catch (IOException e) {e.printStackTrace();} catch (WriterException e) {e.printStackTrace();}}private static BufferedImage genBarcode(String content, int width,int height, String srcImagePath) throws WriterException,IOException {// 读取源图像BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH,IMAGE_HEIGHT, true);int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT];for (int i = 0; i < scaleImage.getWidth(); i++) {for (int j = 0; j < scaleImage.getHeight(); j++) {srcPixels[i][j] = scaleImage.getRGB(i, j);}}Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>();hint.put(EncodeHintType.CHARACTER_SET, "utf-8");hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 生成二维码BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE,width, height, hint);// 二维矩阵转为一维像素数组int halfW = matrix.getWidth() / 2;int halfH = matrix.getHeight() / 2;int[] pixels = new int[width * height];for (int y = 0; y < matrix.getHeight(); y++) {for (int x = 0; x < matrix.getWidth(); x++) {// 读取图片if (x > halfW - IMAGE_HALF_WIDTH&& x < halfW + IMAGE_HALF_WIDTH&& y > halfH - IMAGE_HALF_WIDTH&& y < halfH + IMAGE_HALF_WIDTH) {pixels[y * width + x] = srcPixels[x - halfW+ IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH];} // 在图片四周形成边框else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH&& x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH+ IMAGE_HALF_WIDTH + FRAME_WIDTH)|| (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH+ IMAGE_HALF_WIDTH + FRAME_WIDTH)|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH- IMAGE_HALF_WIDTH + FRAME_WIDTH)|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH&& y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH+ IMAGE_HALF_WIDTH + FRAME_WIDTH)) {pixels[y * width + x] = 0xfffffff;} else {// 此处可以修改二维码的颜色,可以分别制定二维码和背景的颜色;pixels[y * width + x] = matrix.get(x, y) ? 0xff000000: 0xfffffff;}}}BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);image.getRaster().setDataElements(0, 0, width, height, pixels);return image;}/** * 把传入的原始图像按高度和宽度进行缩放,生成符合要求的图标 *  * @param srcImageFile *            源文件地址 * @param height *            目标高度 * @param width *            目标宽度 * @param hasFiller *            比例不对时是否需要补白:true为补白; false为不补白; * @throws IOException */private static BufferedImage scale(String srcImageFile, int height,int width, boolean hasFiller) throws IOException {double ratio = 0.0; // 缩放比例File file = new File(srcImageFile);BufferedImage srcImage = ImageIO.read(file);Image destImage = srcImage.getScaledInstance(width, height,BufferedImage.SCALE_SMOOTH);// 计算比例if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {if (srcImage.getHeight() > srcImage.getWidth()) {ratio = (new Integer(height)).doubleValue()/ srcImage.getHeight();} else {ratio = (new Integer(width)).doubleValue()/ srcImage.getWidth();}AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);destImage = op.filter(srcImage, null);}if (hasFiller) {// 补白BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);Graphics2D graphic = image.createGraphics();graphic.setColor(Color.white);graphic.fillRect(0, 0, width, height);if (width == destImage.getWidth(null))graphic.drawImage(destImage, 0,(height - destImage.getHeight(null)) / 2,destImage.getWidth(null), destImage.getHeight(null),Color.white, null);elsegraphic.drawImage(destImage,(width - destImage.getWidth(null)) / 2, 0,destImage.getWidth(null), destImage.getHeight(null),Color.white, null);graphic.dispose();destImage = image;}return (BufferedImage) destImage;}public static void main(String[] args) {BarcodeFactory.encode("http://coolshell.cn/articles/10590.html",300, 300, "F:\\2013.jpg", "F:\\2013-01.jpg");}}

依赖的jar包:

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



最后生成的二维码如下:

原创粉丝点击