Java生成中间logo的二维码

最近在做商家的模块,需要生成二维码。本来开始想着直接生成二维码就行 ,经过和产品等沟通,需要二维码带上logo等

于是自己写了一个工具类,可以直接使用。有些路径和文件名生成规则需要自己改下,注释已经写的很详细了。希望对大家有所帮助

 

 

package com.allk.utils;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
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;

/**
 * @Author Darren
 * @Time 2017年9月5日 上午10:57:14
 * @Description:二维码生成/解析
 */
public class QRCodeUtils {
	/** 图片格式 */
	public static final String QRCODE_PNG = "png";
	public static final String QRCODE_JPG = "jpg";
	public static final String QRCODE_GIF = "gif";
	public static final String QRCODE_BMP = "bmp";
	public static final String QRCODE_JPEG = "jpeg";
	public static final String QRCODE_PNM = "pnm";

	private static final Integer QRCode$width = 200;
	private static final Integer QRCode$height = 200;

	private static final int QRCOLOR = 0xFF000000; // 默认是黑色
	private static final int BGWHITE = 0xFFFFFFFF; // 背景颜色

	/** 二维码图片存储服务器路径 */
	public static final String QRCode$imgSrc = "/images/qrcode";
	/** 二维码logo图片,默认使用logo图片 */
	public static final String QRCode$logoImg = "/images/public/pinklogo.jpg";

	/**
	 * 不带logo的二维码
	 * 
	 * @param text 二维码附带的信息
	 * @param path 要存放二维码图片的路径
	 * @param format 图片格式 /jpg,png,gif..........
	 * @param file 需要显示在二维码中心位置的小图标(图片)
	 * @throws Exception
	 * @throws WriterException
	 * @throws IOException
	 */
	public static final String[] createQRCode(String text, String path, String format)
			throws WriterException, IOException {
		BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, QRCode$width, QRCode$height,
				getDecodeHintType());
		String filePath = path + QRCode$imgSrc + "/" + createServerImgName();
		File outputFile = new File(filePath);
		MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile);// 生成不带中心位置图标的二维码图片
		String[] img = new String[3];
		img[0] = QRCode$imgSrc + "/" + createServerImgName();
		img[1] = String.valueOf(QRCode$width);
		img[2] = String.valueOf(QRCode$height);
		return img;
	}

	/**
	 * 带logo的二维码
	 * 
	 * @param text 二维码附带的信息
	 * @param path 要存放二维码图片的路径
	 * @param format 图片格式 /jpg,png,gif..........
	 * @param file 需要显示在二维码中心位置的小图标(图片)
	 * @throws Exception
	 * @throws WriterException
	 * @throws IOException
	 */
	public static final String[] createLogoQRCode(String text, String path, String format, File file)
			throws WriterException, IOException {
		BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, QRCode$width, QRCode$height,
				getDecodeHintType());
		int w = bitMatrix.getWidth();
		int h = bitMatrix.getHeight();
		BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
		// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
		for (int x = 0; x < w; x++) {
			for (int y = 0; y < h; y++) {
				image.setRGB(x, y, bitMatrix.get(x, y) ? QRCOLOR : BGWHITE);
			}
		}
		BufferedImage bufferedImage = null;
		if (file != null) {
			bufferedImage = encodeImgLogo(image, file);// 绘制二维码自定义中心位置图片,注意实际格式,更改图片后缀名为满足的格式无效
		} else {
			// logo图片
			String logoPath = path + QRCode$logoImg;
			bufferedImage = encodeImgLogo(image, new File(logoPath));// 绘制二维码中心位置logo图片
		}
		if (bufferedImage == null) {
			return null;
		}
		// 重新生成带logo的二维码图片
		String imgName = createServerImgName();
		String QRClogCode = path + QRCode$imgSrc + "/" + imgName;
		ImageIO.write(bufferedImage, format, new File(QRClogCode));// 生成带中心位置图标的二维码图片

		String[] img = new String[3];
		img[0] = QRCode$imgSrc + "/" + imgName;
		img[1] = String.valueOf(QRCode$width);
		img[2] = String.valueOf(QRCode$height);
		return img;
	}

	/**
	 * 解析二维码,需要javase包。 文件方式解码
	 * 
	 * @param file
	 * @return
	 */
	public static String decode(File file) {
		BufferedImage image;
		try {
			if (file == null || file.exists() == false) {
				throw new Exception(" File not found:" + file.getPath());
			}
			image = ImageIO.read(file);
			return unifiedDecode(image);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 解析二维码 流方式解码
	 * 
	 * @param input
	 * @return
	 */
	public static String decode(InputStream input) {
		BufferedImage image;
		try {
			if (input == null) {
				throw new Exception(" input is null");
			}
			image = ImageIO.read(input);
			return unifiedDecode(image);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private static String unifiedDecode(BufferedImage image) throws NotFoundException {
		LuminanceSource source = new BufferedImageLuminanceSource(image);
		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
		Result result;
		// 解码设置编码方式为:utf-8,
		Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
		hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
		result = new MultiFormatReader().decode(bitmap, hints);
		return result.getText();
	}

	/**
	 * 生成文件名
	 * @return
	 */
	public static final String createServerImgName() {
		UUID serverImgUuid = UUID.randomUUID();
		return DateFormatterUtils.getDateTime() + serverImgUuid.toString();// 文件名
	}

	/**
	 * 设置二维码的格式参数
	 * 
	 * @return
	 */
	public static Map<EncodeHintType, Object> getDecodeHintType() {
		// 用于设置QR二维码参数
		Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
		// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		// 设置编码方式
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
		hints.put(EncodeHintType.MARGIN, 0);
		hints.put(EncodeHintType.MAX_SIZE, 350);
		hints.put(EncodeHintType.MIN_SIZE, 100);
		return hints;
	}

	/**
	 * 二维码绘制logo
	 * 
	 * @param image
	 * @param logoImg
	 *            logo图片文件 格式:JPG, jpg, tiff, pcx, PCX, bmp, BMP, gif, GIF,
	 *            WBMP, png, PNG, raw, RAW, JPEG, pnm, PNM, tif, TIF, TIFF,
	 *            wbmp, jpeg
	 * @throws IOException
	 */
	public static BufferedImage encodeImgLogo(BufferedImage image, File logoImg) throws IOException {
		// String[] names = ImageIO.getReaderFormatNames();
		// System.out.println(Arrays.toString(names));
		// 能读取的图片格式:JPG, jpg, tiff, pcx, PCX, bmp, BMP, gif, GIF, WBMP, png, PNG, raw, RAW, JPEG, pnm, PNM, tif, TIF, TIFF, wbmp, jpeg
		// 读取二维码图片
		// 获取画笔
		Graphics2D g = image.createGraphics();
		// 读取logo图片
		BufferedImage logo = ImageIO.read(logoImg);
		// 设置二维码大小,太大,会覆盖二维码,此处20%
		int logoWidth = logo.getWidth(null) > image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10)
				: logo.getWidth(null);
		int logoHeight = logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10)
				: logo.getHeight(null);
		// 设置logo图片放置位置
		// 中心
		int x = (image.getWidth() - logoWidth) / 2;
		int y = (image.getHeight() - logoHeight) / 2;
		// 右下角,15为调整值
		// int x = twodimensioncode.getWidth() - logoWidth-15;
		// int y = twodimensioncode.getHeight() - logoHeight-15;
		// 开始合并绘制图片
		g.drawImage(logo, x, y, logoWidth, logoHeight, null);
		g.drawRoundRect(x, y, logoWidth, logoHeight, 15, 15);
		// logo边框大小
		g.setStroke(new BasicStroke(2));
		// logo边框颜色
		g.setColor(Color.WHITE);
		g.drawRect(x, y, logoWidth, logoHeight);
		g.dispose();
		logo.flush();
		image.flush();
		return image;
	}

}

 

 

 

 

 

pom.xml

 

<!-- google ZXing Core工具包,生成二维码 -->
		<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>

 

二维码

 

 
 

最简单的生成二维码

pom.xml
 
<!-- 二维码 -->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.3.0</version>
        </dependency>
public String xcxSimulationQrcode(String scene) throws Exception {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode("https://open.weixin.qq.com/sns/getexpappinfo?appid=xxxxxxxxx&path=pages/gradEnroll/gradEnroll.html?scene="+scene,
                BarcodeFormat.QR_CODE, 600, 600);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);

        Base64.Encoder encoder = Base64.getEncoder();
        String text = encoder.encodeToString(outputStream.toByteArray());
        return text;
    }
 

https://open.weixin.qq.com/sns/getexpappinfo?appid=xxxxxxxxx&path=pages/gradEnroll/gradEnroll.html?scene="+scene为需要生成二维码的内容

返回的是base64不加头的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值