下面的代码流程:
生成二维码,由地址下载微信头像,把微信头像放在二维码的画布上,从服务器上下载背景图片,获取坐标参数,把新的二维码放在画布上,通过数据流上传到 七牛云上,最后返回 地址。
开始上代码:
该方法是生成二维码的核心类,
package com.fx.urthinkerManager.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.net.HttpURLConnection;
import java.net.URL;
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;
public class QRcodeUtils {
private static int default_width = 300;
private static int default_height = 300;
/**
* 生成二维码bufferedImage图片
*
* @param content
* 编码内容
* @param barcodeFormat
* 编码类型
* @param width
* 图片宽度
* @param height
* 图片高度
* @param hints
* 设置参数
* @return
*/
public static BufferedImage createQRCode(String content, int width, int height){
width = width<100?default_width:width;
height = height<100?default_height:height;
MultiFormatWriter multiFormatWriter = null;
BitMatrix bm = null;
BufferedImage image = null;
try{
multiFormatWriter = new MultiFormatWriter();
// 获取 简单 默认参数
Map<EncodeHintType, Object> hints = getDecodeHintType();
// 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
bm = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
int w = bm.getWidth();
int h = bm.getHeight();
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, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
}
}
}
catch (WriterException e){
e.printStackTrace();
}
image.flush();
return image;
}
/**
* 给二维码图片添加Logo
*
* @param qrPic
* @param logoPic
*/
public static BufferedImage addLogo(BufferedImage image, InputStream logoPic,String LocalPlace){
try{
// 读取二维码图片,并构建绘图对象
Graphics2D g = image.createGraphics();
// 读取Logo图片
BufferedImage logo = ImageIO.read(logoPic);
// 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码
int widthLogo = logo.getWidth(null)>image.getWidth()*2/10?(image.getWidth()*2/10):logo.getWidth(null);
int heightLogo = logo.getHeight(null)>image.getHeight()*2/10?(image.getHeight()*2/10):logo.getHeight(null);
int x = 0;
int y = 0;
// 计算图片放置位置
if("rig".equals(LocalPlace)){
//logo放在右下角
x = (image.getWidth() - widthLogo);
y = (image.getHeight() - heightLogo);
}else {
//logo放在中心
x = (image.getWidth() - widthLogo) / 2;
y = (image.getHeight() - heightLogo) / 2;
}
//开始绘制图片
g.drawImage(logo, x, y, widthLogo, heightLogo, null);
g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
g.setStroke(new BasicStroke(2));
g.setColor(Color.WHITE);
g.drawRect(x, y, widthLogo, heightLogo);
g.dispose();
logo.flush();
image.flush();
}
catch (Exception e){
e.printStackTrace();
}
return image;
}
/**
* 生成二维码 并 添加 logo
* @param content
* 编码内容
* @param width
* 二维码图片宽度
* @param height
* 二维码图片高度
* @param LogoUrl
* LOGO 地址
*@param LocalPlace
* LOGO 位置 cen 右下角 rig
*/
public static BufferedImage createQRCodeByLogo(String content, int width, int height, String LogoUrl,String LocalPlace){
BufferedImage BufImaLogo = null;
//生成二维码
BufferedImage QRCode = createQRCode(content, width, height);
//获取logo
InputStream inputStreamByGet = getInputStreamByGet(LogoUrl);
if(inputStreamByGet == null){
return QRCode;
}else {
//拼接二维码
BufImaLogo = addLogo(QRCode, inputStreamByGet, LocalPlace);
}
return BufImaLogo;
}
/**
* 生成二维码 并 添加 logo 然后 拼接到 背景图
* @param content
* 编码内容
* @param width
* 二维码图片宽度
* @param height
* 二维码图片高度
* @param LogoUrl
* LOGO 地址 如果 为 0 则 不需要添加
*@param LocalPlace
* LOGO 位置 cen 右下角 rig
* @param x 起始x轴
* @param y 起始y轴
* @param backImageFile 背景图片地址
* @throws IOException
*
*/
public static BufferedImage createQRCodeByLogocoverImage(String content, int width,
int height, String LogoUrl,String LocalPlace,int x,int y,String backImageFilePath){
BufferedImage BufImaLogo = null;
//生成二维码
BufferedImage QRCode = createQRCode(content, width, height);
if (!"0".equals(LogoUrl)){
//获取logo
InputStream inputStreamByGet = getInputStreamByGet(LogoUrl);
if(inputStreamByGet == null){
BufImaLogo = QRCode;
}else {
//拼接二维码
BufImaLogo = addLogo(QRCode, inputStreamByGet, LocalPlace);
}
}
// 读取背景图片
BufferedImage buffImg = redImage(backImageFilePath);
BufferedImage coverImage = coverImage(buffImg, BufImaLogo, x, y, width, height);
return coverImage;
}
/**
* 由地址 把图片读 成 图片数据流
* @param filePath
* 编码内容
*
*/
public static BufferedImage redImage(String filePath){
File file = new File(filePath);
BufferedImage buffImg = null;
try {
buffImg = ImageIO.read(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
buffImg.flush();
return buffImg;
}
// 通过get请求得到读取器响应数据的数据流
public static InputStream getInputStreamByGet(String url) {
try {
HttpURLConnection conn = (HttpURLConnection) new URL(url)
.openConnection();
conn.setReadTimeout(5000);
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = conn.getInputStream();
return inputStream;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 设置二维码的格式参数
*
* @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;
}
/**
* 图片覆盖(覆盖图压缩到width*height大小,覆盖到底图上)
*
* @param baseBufferedImage 底图
* @param coverBufferedImage 覆盖图
* @param x 起始x轴
* @param y 起始y轴
* @param width 覆盖宽度
* @param height 覆盖长度度
* @return
* @throws Exception
*/
public static BufferedImage coverImage(BufferedImage baseBufferedImage, BufferedImage coverBufferedImage, int x, int y, int width, int height) {
// 创建Graphics2D对象,用在底图对象上绘图
Graphics2D g2d = baseBufferedImage.createGraphics();
// 绘制
g2d.drawImage(coverBufferedImage, x, y, width, height, null);
g2d.drawRoundRect(x, y, width, height, 15, 15);
g2d.setStroke(new BasicStroke(2));
g2d.setColor(Color.WHITE);
g2d.drawRect(x, y, width, height);
g2d.dispose();// 释放图形上下文使用的系统资源
return baseBufferedImage;
}
}
下面是一些辅助类
package com.fx.urthinkerManager.utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
*
* 获取路径下的文件及 文件夹
*
* @param path 文件路径
*
* @author zqh
*
*/
public class FileListName {
/**
*
* 获取路径下所有的 文件和 文件夹
*
* @param path 文件路径
*
* @author zqh
*
*/
public static void getAllFolderAndFiles(String path) {
File file = new File(path);
if (file.exists()) {
File[] files = file.listFiles();
if (files.length == 0) {
System.out.println("文件夹是空的!");
return;
} else {
for (File file2 : files) {
if (file2.isDirectory()) {
System.out.println("文件夹:" + file2.getAbsolutePath());
getAllFolderAndFiles(file2.getAbsolutePath());
} else {
System.out.println("文件:" + file2.getAbsolutePath());
System.out.println("文件名 "+file2.getName());
}
}
}
} else {
System.out.println("文件不存在!");
}
}
/**
*
* 获取路径下当前的文件
*
* @param path 文件路径
*
* @author zqh
*
*/
public static List<String> getDireFiles(String path) {
List<String> list = new ArrayList<String>();
File file = new File(path);
if (file.exists()) {
File[] files = file.listFiles();
if (files.length == 0) {
System.out.println("文件夹是空的!");
} else {
for (File file2 : files) {
if (!file2.isDirectory()) {
System.out.println("文件:" + file2.getAbsolutePath());
System.out.println("文件名 "+file2.getName());
list.add(file2.getName());
}
}
}
} else {
System.out.println("文件不存在!");
}
return list;
}
}
package com.fx.urthinkerManager.utils;
import java.io.ByteArrayInputStream;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
public class QiniuyunUtile {
private static String ACCESS_KEY = ""; // 你的access_key
private static String SECRET_KEY = ""; // 你的secret_key
private static String BUCKET_NAME = "";
/*
* 静态内部类的单例方式
*
*/
private static class QiniuyunHolder{
public static QiniuyunUtile instance = new QiniuyunUtile();
}
private QiniuyunUtile(){
ACCESS_KEY = "kasjdklasa;lsda123123123123";
SECRET_KEY = "akdlasd;als12'321312312312312";
BUCKET_NAME = "lased";
}
public static QiniuyunUtile newInstance(){
return QiniuyunHolder.instance;
}
/**
* 华东 Zone.zone0()/华北 Zone.zone1()/华南 Zone.zone2()/北美Zone.zoneNa0()
* http://p0y619yck.bkt.clouddn.com/
*/
// 二进制流 上传 图片
public String uploadPhotosInputStream(ByteArrayInputStream inputStream,String namecode){
Configuration cfg = new Configuration(Zone.zone1());
//密钥配置
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
//创建上传对象
UploadManager uploadManager = new UploadManager(cfg);
// 覆盖上传
String uploadToken = auth.uploadToken(BUCKET_NAME, namecode, 3600, new StringMap().put("insertOnly", 0));
// String uploadToken = auth.uploadToken(BUCKET_NAME);
//调用put方法上传
try {
Response res = uploadManager.put(inputStream,namecode,uploadToken,null, null);
//打印返回的信息
System.out.println(res.bodyString());
} catch (QiniuException e) {
System.out.println(e.response.statusCode);
return "1";
}
return "2";
}
}
package com.fx.service.wxUtil.impl;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.fx.mapper.wxckpe.WxckpeMapper;
import com.fx.po.wxckpe.Wxckpe;
import com.fx.service.wxUtil.QRcodeService;
import com.fx.urthinkerManager.utils.FileListName;
import com.fx.urthinkerManager.utils.QRcodeUtils;
import com.fx.urthinkerManager.utils.QiniuyunUtile;
@Transactional
@Service("qrcodeService")
public class QRcodeServiceImpl implements QRcodeService{
@Autowired
private WxckpeMapper wxckpeMapper;
@Override
public String createQRcode(String openid, String template) {
// 由openid 查询 用户
Wxckpe wxckpe = wxckpeMapper.queryWxckpeByOpenid(openid);
if (wxckpe == null){
return "1"; // openid不正确
}
// 判断是否 有头像地址
String headimgurl = wxckpe.getHeadimgurl();
if ("".equals(headimgurl) || headimgurl == null){
headimgurl = "0";
}
// 拼接 二维码地址
String content = "https://m.media.fuxingnews.com/register.html?wxckpecode="+wxckpe.getWxckpecode();
// 获取 背景图片 /root/fxfile/wxqrcode/template1
String backePath = "/root/fxfile/wxqrcode/" + template;
//String backePath = "E:/ppp/"+template;
List<String> direFiles = FileListName.getDireFiles(backePath);
if (null == direFiles || direFiles.size() ==0){
return "2"; // 模板编号 不正确,或者 模板不存在
}
String filename = direFiles.get(0);
String backeimagePath = "/root/fxfile/wxqrcode/"+template+"/"+filename;
//String backeimagePath = "E:/ppp/"+template+"/"+filename;
//去掉 末尾的.jpg
String latName = filename.split("\\.")[1];
filename = filename.split("\\.")[0];
String[] split = filename.split("_");
Integer width = Integer.valueOf(split[0]);
Integer height = Integer.valueOf(split[1]);
Integer x = Integer.valueOf(split[2]);
Integer y = Integer.valueOf(split[3]);
//生成 二维码
BufferedImage Image = QRcodeUtils.createQRCodeByLogocoverImage(content, width, height, headimgurl, "cen", x, y, backeimagePath);
//数据流转换
ByteArrayOutputStream bs =new ByteArrayOutputStream();
ImageOutputStream imOut;
try {
imOut = ImageIO.createImageOutputStream(bs);
ImageIO.write(Image,"jpeg",imOut);
} catch (IOException e) {
return "3"; //数据转换异常
}
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bs.toByteArray());
//上传 七牛云
QiniuyunUtile newInstance = QiniuyunUtile.newInstance();
String result = newInstance.uploadPhotosInputStream(byteArrayInputStream, wxckpe.getWxckpecode()+ "." + latName);
if("1".equals(result)){
return "4"; //上传错误
}
String resultPath = "http://p0y619yck.bkt.clouddn.com/"+wxckpe.getWxckpecode()+ "." + latName+ "?v=" + String.valueOf((int)((Math.random()*9+1)*1000));
return resultPath;
}
}