java 使用com.google.zxing 提供的架包 生成二维码图片 附加功能(插入logo、添加文本)
1:先生成二维码代码
package com.myFirstSpring.test;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
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.common.BitMatrix;
public class Qrcoe
{
// 二维码尺寸
private static final int QRCODE_SIZE = 400;
// LOGO宽度
private static final int WIDTH = 60;
// LOGO高度
private static final int HEIGHT = 60;
//logo图片的路径
private static final String logopath = "D://Qrcoe/logo.jpg";
public static void main(String[] args) throws Exception
{
String url =""; //二维码访问地址
//fileName 二维码图片名称
String fileName = "";//new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".jpg";
//String path1 = request.getSession().getServletContext().getRealPath("/images/320240jpg.jpg");//获取图像在项目中的路径
//path 二维码存放路径
String path ="D://Qrcoe/";// FileSystemView.getFileSystemView().getHomeDirectory() + File.separator + "testQrcode";
for (int i = 1; i < 2; i++) {
url = "http://m.xinjuenet.com/evaluation_details?id=28&channel="+i+"";
fileName = i+".jpg";
createQrCode(url, path, fileName,logopath); //生成二维码图片
File qrcFile = new File("D://Qrcoe/",fileName);
pressText("心觉-咨询平台", qrcFile, 5, Color.black, 16); //图片上添加文本 居中在留白区域
}
}
/**
* 生成二维码
* @param url 访问地址 或者文本内容
* @param path 生成文件存放路径
* @param fileName 生成文件名称
* @param logopath logo图标路径
* @return
*/
public static String createQrCode(String url, String path, String fileName,String logopath)
{
try
{
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); //设置编码方式
hints.put(EncodeHintType.MARGIN, 4); 二维码空白区域,最小为0也有白边,只是很小,最小是6像素左右
BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
File file = new File(path, fileName);
if (file.exists()
|| ((file.getParentFile().exists() || file.getParentFile().mkdirs()) && file.createNewFile()))
{
writeToFile(bitMatrix, "jpg", file,logopath);
System.out.println("搞定:" + file);
}
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
static void writeToFile(BitMatrix matrix, String format, File file,String logopath) throws IOException
{
BufferedImage image = toBufferedImage(matrix,logopath);
if (!ImageIO.write(image, format, file))
{
throw new IOException("Could not write an image of format " + format + " to " + file);
}
}
static void writeToStream(BitMatrix matrix, String format, OutputStream stream,String logopath) throws IOException
{
BufferedImage image = toBufferedImage(matrix,logopath);
if (!ImageIO.write(image, format, stream))
{
throw new IOException("Could not write an image of format " + format);
}
}
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static BufferedImage toBufferedImage(BitMatrix matrix,String logopath)
{
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
try {
// 插入图片 添加logo
if(logopath !=null && !"".equals(logopath)){
insertImage(image, logopath, true);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return image;
}
/**
* 在生成的二维码中插入图片
* @param source
* @param imgPath
* @param needCompress
* @throws Exception
*/
static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
File file1 = new File(imgPath);
if (!file1.exists()) {
System.err.println("" + imgPath + " 该文件不存在!");
return;
}
Image src = ImageIO.read(new File(imgPath));
int width = src.getWidth(null);
int height = src.getHeight(null);
if (needCompress) { // 压缩LOGO
if (width > WIDTH) {
width = WIDTH;
}
if (height > HEIGHT) {
height = HEIGHT;
}
Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(image, 0, 0, null); // 绘制缩小后的图
g.dispose();
src = image;
}
// 插入LOGO
Graphics2D graph = source.createGraphics();
int x = (QRCODE_SIZE - width) / 2;
int y = (QRCODE_SIZE - height) / 2;
graph.drawImage(src, x, y, width, height, null);
Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
graph.setStroke(new BasicStroke(3f));
graph.draw(shape);
graph.dispose();
}
/**
* 给二维码图片加上文字
* @param pressText 文字
* @param qrFile 二维码文件
* @param fontStyle
* @param color
* @param fontSize
*/
public static void pressText(String pressText, File qrFile, int fontStyle, Color color, int fontSize) throws Exception {
pressText = new String(pressText.getBytes(), "utf-8");
Image src = ImageIO.read(qrFile);
int imageW = src.getWidth(null);
int imageH = src.getHeight(null);
BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.drawImage(src, 0, 0, imageW, imageH, null);
//设置画笔的颜色
g.setColor(color);
//设置字体
Font font = new Font("宋体", fontStyle, fontSize);
FontMetrics metrics = g.getFontMetrics(font);
//文字在图片中的坐标 这里设置在中间
int startX = 150; //(WIDTH - metrics.stringWidth(pressText)) / 2;
int startY = 380;//HEIGHT/2;
g.setFont(font);
g.drawString(pressText, startX, startY);
g.dispose();
FileOutputStream out = new FileOutputStream(qrFile);
ImageIO.write(image, "JPEG", out);
out.close();
System.out.println("二维码添加文本成功");
}
}
2:把生成的所有二维码图片打包成压缩包文件
package com.myFirstSpring.test;
/**
* @author tqf
* @version 创建时间:2019-9-25 下午1:50:02
* 类说明:文件打包成压缩包
*/
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import com.cloopen.rest.sdk.utils.DateUtil;
public class ZipUtil {
public static void main(String[] args){
String sourceFilePath = "D://Qrcoe/";
String zipFilePath = "D://Qrcoe/";
String fileName = DateUtil.dateToStr(new Date(),"yyyyMMddHHmmss");
String fn = ZipUtil.fileToZip(sourceFilePath, zipFilePath, fileName);
System.out.println(fn);
}
/**
* 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下
* @param sourceFilePath :待压缩的文件路径
* @param zipFilePath :压缩后存放路径
* @param fileName :压缩后文件的名称
* @return
*/
public static String fileToZip(String sourceFilePath,String zipFilePath,String fileName){
File sourceFile = new File(sourceFilePath);
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
ZipOutputStream zos = null;
//判断源文件是否存在
if(!sourceFile.exists()){
System.out.println("待压缩的文件目录:"+sourceFilePath+"不存在.");
}else{
try {
File zipFile = new File(zipFilePath + "/" + fileName +".rar");
//判断压缩后文件是否会重复
if(zipFile.exists()){
System.out.println(zipFilePath + "目录下已存在名字为" + fileName +".rar" +"文件");
}else{
//每次生成压缩包之前先删除原有的压缩包
zipFile.delete();
//获取源文件夹下的所有文件
File[] sourceFiles = sourceFile.listFiles();
if(null == sourceFiles || sourceFiles.length<1){
System.out.println("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");
}else{
//先删除之前的压缩包文件
for(int i=0; i<sourceFiles.length; i++){
if(sourceFiles[i].getName().indexOf(".rar")!=-1){
File zipFile2 = new File(sourceFiles[i].getPath());
zipFile2.delete();
break;
}
}
//重新获取文件夹所以文件
sourceFiles = sourceFile.listFiles();
fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte[] bufs = new byte[1024*10];
for(int i=0; i<sourceFiles.length; i++){
//创建ZIP实体,并添加进压缩包
ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
zos.putNextEntry(zipEntry);
//读取待压缩的文件并写进压缩包里
fis = new FileInputStream(sourceFiles[i]);
bis = new BufferedInputStream(fis, 1024*10);
int read = 0;
while((read=bis.read(bufs, 0, 1024*10)) != -1){
zos.write(bufs,0,read);
}
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally{
//关闭流
try {
if(null != bis) bis.close();
if(null != zos) zos.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
return fileName + ".rar";
}
}
效果图如下