现在完成任务把代码发出来标记一下,方便以后使用。
format 方法可能存在文字太长需要换行
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.util.HashMap; import java.util.Map; import java.util.Vector; 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; import com.iec.o2o.model.activity.vo.OfflineActProductImageVo; /** * @author yonglongwang * * 2017年6月7日 下午5:06:07 */ public class QRCodeMain{ private static int BLACK = 0x000000; private static int WHITE = 0xFFFFFF; // 计算字符串的宽度 public static int getFontWidth(Graphics g, String str){ int width = 0; for(int i=0;i<str.length();i++){ // 默认字体样式计算,否则需要传参 width += g.getFontMetrics(new Font("宋体", Font.PLAIN, 20)).charWidth(str.charAt(i)); } return width; } /* * 字符串切割,实现字符串自动换行 * maxWidth 画布的宽 **/ @SuppressWarnings({ "rawtypes", "unchecked" }) public static String[] format(Graphics g, String text, int maxWidth, Font ft) { String[] result = null; Vector tempR = new Vector(); int lines = 0; int len = text.length(); int index0 = 0; int index1 = 0; boolean wrap; while (true) { int widthes = 0; wrap = false; for (index0 = index1; index1 < len; index1++) { if (text.charAt(index1) == '\n') { index1++; wrap = true; break; } widthes = g.getFontMetrics(ft).charWidth(text.charAt(index1)) + widthes; if (widthes > maxWidth) { break; } } lines++; if (wrap) { tempR.addElement(text.substring(index0, index1 - 1)); } else { tempR.addElement(text.substring(index0, index1)); } if (index1 >= len) { break; } } result = new String[lines]; tempR.copyInto(result); return result; } public static void main(String[] args) throws Exception{ // 写到图片上的参数 OfflineActProductImageVo offlineVo = new OfflineActProductImageVo(); // 创建画布 BufferedImage img = new BufferedImage(400, 475, BufferedImage.TYPE_INT_RGB); // 得到画笔 Graphics graphics = img.getGraphics(); // 白色背景 graphics.setColor(Color.white); // 填充白色范围 graphics.fillRect(0, 0, 400, 475); // 添加二维码 MultiFormatWriter writer = new MultiFormatWriter(); Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); hints.put(EncodeHintType.MARGIN, 3); //二维码边框宽度 BitMatrix bm = writer.encode("二维码内容信息", BarcodeFormat.QR_CODE, 400, 400 , hints); int w = bm.getWidth(); int h = bm.getHeight(); for(int x=0;x<w;x++){ for(int y=0;y<h;y++){ img.setRGB(x, 70+y, bm.get(x, y) ? BLACK : WHITE); } } graphics.setColor(Color.black); graphics.setFont(new Font("宋体", Font.PLAIN, 20)); // 添加商品描述 graphics.drawString(offlineVo.getTitle(), (400-getFontWidth(graphics,offlineVo.getTitle()))/2, 20); graphics.drawString("原价:"+offlineVo.getShopPrice(), (400-getFontWidth(graphics,"原价:"+offlineVo.getShopPrice()))/2, 45); graphics.drawString("折扣价:"+offlineVo.getActPrice(), (400-getFontWidth(graphics,"折扣价:"+offlineVo.getActPrice()))/2, 70); graphics.drawString("所需积分:"+offlineVo.getBonusPoint(), (400-getFontWidth(graphics,"所需积分:"+offlineVo.getBonusPoint()))/2, 95); // 这里的坐标 y 20、45、70 都是自己随意定的高度,因为我的字体宽度为20,上面有定义 try{ ImageIO.write(img, "png", new File("E:/test.png")); // 保存本地 //ImageIO.write(img, "png", response.getOutputStream()); // 文件流输出到页面或下载 }catch(Exception e){ e.printStackTrace(); } } }
备注:
如果在页面显示图片的话就直接就是url地址。如果需要下载则必须在后台方法设置 HttpServletResponse 属性
response.setContentType("application/octet-stream"); response.setHeader("Accept-Ranges", "bytes"); response.setHeader("Content-Disposition", "attachment;fileName=qrcode.png");