二维码的生成,需要通过GOOGLE提供的ZXING来完成,而水印图片的合成则通过JDK自带的com.sum.image.code.*包来完成
首选,通过http://www.baidu.com搜索zxing包下载,压缩包很大里面包含了j2se、android用到的jar及示例。
旅程开始了。。。。。。。狂气、狂气
1. 定义一个图片生成器,实现了二维码的生成及logo的添加
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import org.apache.log4j.Logger;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
/**
* 二维码生成器
* @Description:
* @author wuyan
* @date 2015年12月18日 下午6:18:37
*/
public class Code2dBuilder {
/**
* logo与二维码图片的宽、高比例
*/
private double icon_w_proportion = 0.2 ;
private double icon_h_proportion = 0.2 ;
/**
* 生在指定大小的二维码图片
*
* @author wuyan
* @date 2015年12月21日 下午6:10:58
* @param text 用于生成二维的信息
* @param output 二维码输出流
* @param width 宽度
* @param height 高度
* @param format 图片格式
* @throws Exception
*/
public static void build2Code(String text,OutputStream output,int width,int height,String format) throws Exception {
Hashtable hints = new Hashtable();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(text,
BarcodeFormat.QR_CODE, width, height, hints);
// MatrixToImageConfig config = new MatrixToImageConfig(MatrixToImageConfig.WHITE,MatrixToImageConfig.BLACK);
MatrixToImageConfig config = new MatrixToImageConfig();
MatrixToImageWriter.writeToStream(bitMatrix, format, output,config);
}
/**
* 添加水印
* 通过输入两张图片的流信息来制作合成图片
* @author wuyan
* @date 2015年12月21日 下午6:12:11
* @param background 底层图片流
* @param logo logo图片流
* @param dest 合成结果流
* @throws Exception
*/
public void addicon(InputStream background,InputStream logo,OutputStream dest) throws Exception{
BufferedImage canvas =ImageIO.read(background);
BufferedImage icon =ImageIO.read(logo);
Graphics g = canvas.getGraphics();
// int x = (int) canvas.getWidth() /2 - icon.getWidth() / 2 -icon_x_offset;
// int y = (int) canvas.getHeight() /2 - icon.getHeight() /2 - icon_y_offset;
// int w = (int) (canvas.getWidth() * icon_w_proportion) ;
// int h = (int) (canvas.getHeight() * icon_h_proportion) ;
int w = (int) (canvas.getWidth() * icon_w_proportion) ;
int h = (int) (canvas.getHeight() * icon_h_proportion) ;
int x = (int) canvas.getWidth() /2 - w / 2 ;
int y = (int) canvas.getHeight() /2 - h /2 ;
g.drawImage(icon,x,y,w,h,null);
JPEGImageEncoder enc=JPEGCodec.createJPEGEncoder(dest);
enc.encode(canvas);
dest.flush();
dest.close();
}
/**
* 添加水印
* 通过输入两张图片的流信息来制作合成图片
* @author wuyan
* @date 2015年12月21日 下午6:12:11
* @param background 底层图片流
* @param logo logo图片流
* @param x 指定横坐标
* @param y 指定纵坐标
* @param dest 合成结果流
* @throws Exception
*/
public void addicon(InputStream background,InputStream logo,int x,int y,int w,int h,OutputStream dest) throws Exception{
BufferedImage canvas =ImageIO.read(background);
BufferedImage icon =ImageIO.read(logo);
Graphics g = canvas.getGraphics();
g.drawImage(icon,x,y,w,h,null);
JPEGImageEncoder enc=JPEGCodec.createJPEGEncoder(dest);
enc.encode(canvas);
dest.flush();
dest.close();
}
/**
* @param icon_w_proportion the icon_w_proportion to set
*/
public void setIcon_w_proportion(double icon_w_proportion) {
this.icon_w_proportion = icon_w_proportion;
}
/**
* @param icon_h_proportion the icon_h_proportion to set
*/
public void setIcon_h_proportion(double icon_h_proportion) {
this.icon_h_proportion = icon_h_proportion;
}
}
2. 定义一个jsp页面用于展示二维码信息code2d.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*" %>
<%@ page import="org.apache.log4j.Logger" %>
<%@ page import="code2d.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
String icon = "./logo.png" ;
String path=request.getSession().getServletContext().getRealPath("/");
String text = request.getParameter("text");
Logger logger = Logger.getRootLogger();
if (text == null)
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
logger.info("text:" + text);
try {
ByteArrayOutputStream result = new ByteArrayOutputStream();
//创建二维码
Code2dBuilder code2dBuilder = new Code2dBuilder();
code2dBuilder.build2Code(text, result,370,370,"jpg");
//判断图标
File iconfile = new File(path + icon) ;
if (iconfile.exists()){
InputStream icon_in = new FileInputStream(iconfile);
ByteArrayInputStream code2d_in = new ByteArrayInputStream(result.toByteArray());
result = new ByteArrayOutputStream();
//添加图标
code2dBuilder.addicon(code2d_in,icon_in,result);
code2d_in.close();
icon_in.close();
}
File outfile = new File(path + "/out.png");
outfile.createNewFile();
FileOutputStream fos = new FileOutputStream(outfile);
fos.write(result.toByteArray());
fos.close();
result.flush();
result.close();
out.print("<img src='./out.png'/>");
} catch (Exception e) {
logger.error(e);
e.printStackTrace();
out.print(e.getClass().getName() + " " + e.getMessage());
}
%>
3. 访问方式
http://localhost:8080/code2d.jsp?text=http://www.baidu.com
text:即想要生成二维码的内容
logo:已经在jsp页面中指定了固定的路径地址