赞
踩
由于自己最近在学设计模式,就想着如何能运用到自己工作的项目中。找了半天,想起自己之前写的一段关于生成二维码图片的代码。后面由于同事的需求不同,他们在里面添加了一下其它逻辑的代码。现在感觉这段代码已经不太好被扩展维护了。于是就用选择了设计模式中的模板方法重新进行设计。(重构后的代码布局如图:)
下面是代码的实现:
OperateImage 工具类:
import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Iterator; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; /** * 生成二维码的工具类 * @version 1.0 */ public class OperateImage { // ===源图片路径名称如:c:\1.jpg private String srcpath; // ===剪切图片存放路径名称.如:c:\2.jpg private String subpath; // ===剪切点x坐标 private int x; private int y; // ===剪切点宽度 private int width; private int height; public OperateImage() { } public OperateImage(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } /** * 对图片裁剪,并把裁剪完蛋新图片保存 。 */ public void cut() throws IOException { FileInputStream is = null; ImageInputStream iis = null; try { // 读取图片文件 is = new FileInputStream(srcpath); /* * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 声称能够解码指定格式。 * 参数:formatName - 包含非正式格式名称 .(例如 "jpeg" 或 "tiff")等 。 */ Iterator<ImageReader> it = ImageIO.getImageReadersBySuffix("jpg"); ImageReader reader = it.next(); // 获取图片流 iis = ImageIO.createImageInputStream(is); /* * <p>iis:读取源.true:只向前搜索 </p>.将它标记为 ‘只向前搜索’。 * 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。 */ reader.setInput(iis, true); /* * <p>描述如何对流进行解码的类<p>.用于指定如何在输入时从 Java Image I/O * 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件 将从其 ImageReader 实现的 * getDefaultReadParam 方法中返回 ImageReadParam 的实例。 */ ImageReadParam param = reader.getDefaultReadParam(); /* * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域,通过 Rectangle 对象 * 的左上顶点的坐标(x,y)、宽度和高度可以定义这个区域。 */ Rectangle rect = new Rectangle(x, y, width, height); // 提供一个 BufferedImage,将其用作解码像素数据的目标。 param.setSourceRegion(rect); /* * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将 它作为一个完整的 * BufferedImage 返回。 */ BufferedImage bi = reader.read(0, param); // 保存新图片 ImageIO.write(bi, "jpg", new File(subpath)); } finally { if (is != null) is.close(); if (iis != null) iis.close(); } } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public String getSrcpath() { return srcpath; } public void setSrcpath(String srcpath) { this.srcpath = srcpath; } public String getSubpath() { return subpath; } public void setSubpath(String subpath) { this.subpath = subpath; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public static void main(String[] args) { OperateImage operateImage = new OperateImage(20, 20, 260, 260); operateImage.setSrcpath("C:/Users/74532/Desktop/bbb.JPG"); operateImage.setSubpath("C:/Users/74532/Desktop/bbb.JPG"); try { operateImage.cut(); } catch (IOException e) { e.printStackTrace(); } } }
QrCodeTemplate 模板类:
import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import com.hx.main.QREncoder; /** * 抽象基类,为所有子类提供模板框架 * @version 1.0 */ public abstract class QrCodeTemplate { //生成图片宽度 private int imgWidth; //生成图片高度 private int imgHeight; //剪切点x坐标 private int cutX; //剪切点y坐标 private int cutY; //剪切点宽度 private int cutWidth; //剪切点高度 private int cutHeight; { //初始默认参数 imgWidth = 300; imgHeight = 300; cutX = 32; cutY = 32; cutWidth = 235; cutHeight = 235; } public QrCodeTemplate() { } /** * 该构造器提供修改默认参数入口 * @param imgWidth 生成图片宽度 * @param imgHeight 生成图片高度 * @param cutX 剪切点x坐标 * @param cutY 剪切点y坐标 * @param cutWidth 剪切点宽度 * @param cutHeight 剪切点高度 */ public QrCodeTemplate(int imgWidth, int imgHeight, int cutX, int cutY, int cutWidth, int cutHeight) { super(); this.imgWidth = imgWidth; this.imgHeight = imgHeight; this.cutX = cutX; this.cutY = cutY; this.cutWidth = cutWidth; this.cutHeight = cutHeight; } public final byte[] runTemplate(){ //①生成二维码图片地址 String imgPath = qrCodePath(); //②创建二维码文件 File file = createFile(imgPath); //③获取需要生成二维码的url String targetUrl = qrCodeTargetUrl(); //④生成二维码图片 qrCodeCreate(targetUrl, imgPath, imgWidth, imgHeight); //⑤将图片转为为JPG格式 change2jpg(file); //⑥裁剪二维码 qrCodeTrim(imgPath, cutX, cutY, cutWidth, cutHeight); //⑦获取二维码信息 byte[] buffer = qrCodeBufferInfo(file,isDeleteImg()); return buffer; } /** * 二维码生成的路径 * @return */ protected abstract String qrCodePath(); /** * 二维码目标url * @return */ protected abstract String qrCodeTargetUrl(); /** * 是否删除生成的二维码图片 * @return */ protected Boolean isDeleteImg() { return true; } /** * 生成二维码 * @param url 二维码目标url * @param imgPath 生成图片地址 * @param width 图片宽度 * @param height 图片高度 */ private void qrCodeCreate(String url, String imgPath, int width, int height) { QREncoder qrEncode = new QREncoder(); qrEncode.encode(url, imgPath, width, height); } /** * 生成文件 * @param directory 目录文件 * @param filepath 文件全路径 * @return 返回二维码文件 */ private File createFile(String filepath){ int index = filepath.lastIndexOf("\\"); String directory = filepath.substring(0, index); File file = new File(filepath); try { if (!new File(directory).exists()) { new File(directory).mkdirs(); } file.createNewFile(); } catch (IOException e2) { throw new RuntimeException("创建文件失败"); } return file; } /** * 将图片转为为JPG格式 * @param file */ private void change2jpg(File file) { BufferedImage bufferedImage; try { bufferedImage = ImageIO.read(file); BufferedImage newBufferedImage = new BufferedImage( bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB); // TYPE_INT_RGB:创建一个RBG图像,24位深度,成功将32位图转化成24位 newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, Color.WHITE, null); // write to jpeg file ImageIO.write(newBufferedImage, "jpg", file); } catch (IOException e) { throw new RuntimeException("转为JPG失败"); } } /** * 裁剪图片 * @param imgPath 图片路径 * @param x 剪切点x坐标 * @param y 剪切点y坐标 * @param width 剪切点宽度 * @param height 剪切点高度 */ private void qrCodeTrim(String imgPath, int c_x, int c_y, int c_width, int c_height){ OperateImage operateImage = new OperateImage(c_x, c_y, c_width, c_height); operateImage.setSrcpath(imgPath); operateImage.setSubpath(imgPath); try { //进行二维码图片裁剪 operateImage.cut(); } catch (IOException e) { throw new RuntimeException("二维码图片剪切失败"); } } /** * 删除二维码文件 * @param file * @return 返回二维码图片byte数组 */ private byte[] qrCodeBufferInfo(File file,Boolean isDelete) { InputStream inputStream = null; byte[] buffer = null; try { inputStream = new FileInputStream(file); int i = inputStream.available(); // 得到文件大小 buffer = new byte[i]; inputStream.read(buffer); } catch (Exception e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } // 删除二维码图片 if(isDelete){ file.delete(); } } return buffer; } }
BusinessLicenseNewQrCode 子类:
import javax.servlet.http.HttpServletRequest; /** * 实现子类 * @version 1.0 */ public class BusinessLicenseNewQrCode extends QrCodeTemplate{ private String GSURL="你的url"; /** * 构造方法:缺省二维码大小 * @param uniscid */ public BusinessLicenseNewQrCode(String uniscid){ super(); this.GSURL += uniscid; } /** * 构造方法:自定义二维码图片大小 * @param uniscid 统一信用代码 * @param imgWidth 生成图片宽度 * @param imgHeight 生成图片高度 * @param cutX 剪切点x坐标 * @param cutY 剪切点y坐标 * @param cutWidth 剪切点宽度 * @param cutHeight 剪切点高度 */ public BusinessLicenseNewQrCode(String uniscid, int imgWidth, int imgHeight, int cutX, int cutY, int cutWidth, int cutHeight){ super(imgWidth, imgHeight, cutX, cutY, cutWidth, cutHeight); this.GSURL += uniscid; } /** * 二维码生成保存路径 */ @Override protected String qrCodePath() { String dirPath = System.getProperty("user.dir") + "/app/font/qrCodeGS"; String imgPath = dirPath+ "\\" + UUIDUtil.getUUID() + ".jpg"; return imgPath; } /** * 二维码目标url */ @Override protected String qrCodeTargetUrl() { return GSURL; } /** * 钩子方法 * 获取二维码数据后是否删除生成的二维码图片 */ @Override protected Boolean isDeleteImg() { // TODO Auto-generated method stub return super.isDeleteImg(); } }
MaterialsReceiptQrCode 子类:
import javax.servlet.http.HttpServletRequest; /** * 实现子类:收取材料凭据二维码的实现 * @version 1.0 */ public class MaterialsReceiptQrCode extends QrCodeTemplate{ //收取材料凭证二维码生成url private String RCURL="你的url"; /** * 构造方法:缺省二维码大小 * @param gid 业务id * @param regorg 登记机关 */ public MaterialsReceiptQrCode(String gid, String regorg){ super(); this.RCURL += "?gid=" + gid + "®org=" + regorg; } /** * 构造方法:自定义二维码图片大小 * @param gid 业务id * @param regorg 登记机关 * @param imgWidth 生成图片宽度 * @param imgHeight 生成图片高度 * @param cutX 剪切点x坐标 * @param cutY 剪切点y坐标 * @param cutWidth 剪切点宽度 * @param cutHeight 剪切点高度 */ public MaterialsReceiptQrCode(String gid, String regorg, int imgWidth, int imgHeight, int cutX, int cutY, int cutWidth, int cutHeight){ super(imgWidth, imgHeight, cutX, cutY, cutWidth, cutHeight); this.RCURL += "?gid=" + gid + "®org=" + regorg; } /** * 二维码生成保存路径 */ @Override protected String qrCodePath() { String dirPath = System.getProperty("user.dir") + "/app/font/qrCodeGS"; String imgPath = dirPath+ "\\" + UUIDUtil.getUUID() + ".jpg"; return imgPath; } /** * 二维码目标url */ @Override protected String qrCodeTargetUrl() { return RCURL; } /** * 钩子方法 * 获取二维码数据后是否删除生成的二维码图片 */ @Override protected Boolean isDeleteImg() { // TODO Auto-generated method stub return super.isDeleteImg(); } }
调用方式SpringMVC:
SpringMvc后端: /** * 二维码生成 * * @param request * @param response */ @RequestMapping("/createQRCode") public void createCertQRCode(HttpServletRequest request, HttpServletResponse response) { //生成二维码模块对象 QrCodeTemplate qrCode = new BusinessLicenseNewQrCode(“param01”); //执行模板获取二维码二进制数据 byte[] buffer = qrCode.runTemplate(); /*//生成二维码模块对象 QrCodeTemplate qrCode = new MaterialsReceiptQrCode(“param01”, “param02”); //执行模板获取二维码二进制数据 byte[] buffer = qrCode.runTemplate();*/ //输出数据 returnImg(buffer, response); } // 向客户端输出图片 public void returnImg(byte[] buffer, HttpServletResponse response){ OutputStream toClient = null; try { // 设置返回的文件类型 response.setContentType("image/*"); // 得到向客户端输出二进制数据的对象 toClient = response.getOutputStream(); // 输出数据 toClient.write(buffer); } catch (Exception e) { e.printStackTrace(); } finally { if (toClient != null) { try { toClient.close(); } catch (IOException e) { e.printStackTrace(); } } } } 前端HTML: <img src="/createQRCode.do"></img>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。