第一步:受权获取小程序二维码java
https://blog.csdn.net/weixin_37545129/article/details/88699623web
第二步:准备好二维码背景图存放到本地文件夹中算法
第三步:开始绘图json
package com.ruoyi.web.pay.config; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.geom.Ellipse2D; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.UUID; import javax.imageio.ImageIO; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.utils.http.HttpUtils; /** * 把两张图片合并 * * @author WuHao * @version $Id: Pic.java, v 0.1 2019-10-26 下午3:21:23 1111 Exp $ */ public class DrawingUtils { private Font font = new Font("宋体", Font.BOLD, 40); // 添加字体的属性设置 private Graphics2D g = null; private Graphics2D J = null; private int fontsize = 0; private int x = 0; private int y = 0; /** * 导入本地图片到缓冲区 */ public BufferedImage loadImageLocal(String imgName) { try { return ImageIO.read(new File(imgName)); } catch (IOException e) { System.out.println(e.getMessage()); } return null; } /** * 导入网络图片到缓冲区 */ public BufferedImage loadImageUrl(String imgName) { try { URL url = new URL(imgName); return ImageIO.read(url); } catch (IOException e) { System.out.println(e.getMessage()); } return null; } /** * 生成新图片到本地 */ public void writeImageLocal(String newImage, BufferedImage img) { if (newImage != null && img != null) { try { File outputfile = new File(newImage); ImageIO.write(img, "jpg", outputfile); } catch (IOException e) { System.out.println(e.getMessage()); } } } /** * 设定文字的字体等 */ public void setFont(String fontStyle, int fontSize) { this.fontsize = fontSize; this.font = new Font(fontStyle, Font.PLAIN, fontSize); } /** * 修改图片,返回修改后的图片缓冲区(只输出一行文本) */ public BufferedImage modifyImage(BufferedImage img, Object content, int x, int y, Font font, Color color) { try { g = img.createGraphics(); g.setBackground(Color.WHITE); g.setColor(color);// 设置字体颜色 if (font != null) g.setFont(font); // 验证输出位置的纵坐标和横坐标 if (content != null) { g.drawString(content.toString(), x, y); } g.dispose(); } catch (Exception e) { System.out.println(e.getMessage()); } return img; } /** * 修改图片,返回修改后的图片缓冲区(输出多个文本段) xory:true表示将内容在一行中输出;false表示将内容多行输出 */ public BufferedImage modifyImage(BufferedImage img, Object[] contentArr, int x, int y, boolean xory) { try { int w = img.getWidth(); int h = img.getHeight(); g = img.createGraphics(); g.setBackground(Color.WHITE); g.setColor(Color.RED); if (this.font != null) g.setFont(this.font); // 验证输出位置的纵坐标和横坐标 if (x >= h || y >= w) { this.x = h - this.fontsize + 2; this.y = w; } else { this.x = x; this.y = y; } if (contentArr != null) { int arrlen = contentArr.length; if (xory) { for (int i = 0; i < arrlen; i++) { g.drawString(contentArr[i].toString(), this.x, this.y); this.x += contentArr[i].toString().length() * this.fontsize / 2 + 5;// 从新计算文本输出位置 } } else { for (int i = 0; i < arrlen; i++) { g.drawString(contentArr[i].toString(), this.x, this.y); this.y += this.fontsize + 2;// 从新计算文本输出位置 } } } g.dispose(); } catch (Exception e) { System.out.println(e.getMessage()); } return img; } /** * 修改图片,返回修改后的图片缓冲区(只输出一行文本) * * 时间:2007-10-8 * * @param img * @return */ public BufferedImage modifyImageYe(BufferedImage img) { try { int w = img.getWidth(); int h = img.getHeight(); g = img.createGraphics(); g.setBackground(Color.WHITE); g.setColor(Color.blue);// 设置字体颜色 if (this.font != null) g.setFont(this.font); g.drawString("www.hi.baidu.com?xia_mingjian", w - 85, h - 5); g.dispose(); } catch (Exception e) { System.out.println(e.getMessage()); } return img; } public BufferedImage modifyImagetogeter(BufferedImage b, BufferedImage d, int X, int Y) { try { int w = b.getWidth(); int h = b.getHeight(); g = d.createGraphics(); g.drawImage(b, X, Y, w, h, null); g.dispose(); } catch (Exception e) { System.out.println(e.getMessage()); } return d; } /** * 从url中读取图片 * * @param urlHttp * @param path */ public static String getPicture(String urlHttp, String path) { int machineId = 1;// 最大支持1-9个集群机器部署 int hashCodeV = UUID.randomUUID().toString().hashCode(); if (hashCodeV < 0) {// 有多是负数 hashCodeV = -hashCodeV; } String file = path + machineId + String.format("%015d", hashCodeV) + ".jpg"; try { URL url = new URL(urlHttp); BufferedImage img = ImageIO.read(url); ImageIO.write(img, "jpg", new File(file)); } catch (Exception e) { e.printStackTrace(); } return file; } public static void pichead(String url, String path) throws MalformedURLException, IOException { BufferedImage avatarImage = ImageIO.read(new URL(url)); int width = 84;// 若是剪切出来的图片画质模糊,请将width 调大点. // 透明底的图片 BufferedImage formatAvatarImage = new BufferedImage(width, width, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D graphics = formatAvatarImage.createGraphics(); // 把图片切成一个圓 graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 留一个像素的空白区域,这个很重要,画圆的时候把这个覆盖 int border = 1; // 图片是一个圆型 Ellipse2D.Double shape = new Ellipse2D.Double(border, border, width - border * 2, width - border * 2); // 须要保留的区域 graphics.setClip(shape); graphics.drawImage(avatarImage, border, border, width - border * 2, width - border * 2, null); graphics.dispose(); // 在圆图外面再画一个圆 // 新建立一个graphics,这样画的圆不会有锯齿 graphics = formatAvatarImage.createGraphics(); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int border1 = 3; // 画笔是4.5个像素,BasicStroke的使用能够查看下面的参考文档 // 使画笔时基本会像外延伸必定像素,具体能够本身使用的时候测试 Stroke s = new BasicStroke(4.5F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); graphics.setStroke(s); graphics.setColor(Color.WHITE); graphics.drawOval(border1, border1, width - border1 * 2, width - border1 * 2); graphics.dispose(); OutputStream os = new FileOutputStream(path);// 发布项目时,如:Tomcat 他会在服务器 本地tomcat webapps文件下建立此文件名 ImageIO.write(formatAvatarImage, "PNG", os); os.close(); } /** * 删除文件 * * @param file */ public static void filedel(String filedel) { File file = new File(filedel); if (!file.exists()) { System.out.println("文件不存在"); } else { System.out.println("存在文件"); file.delete();// 删除文件 } } public static void main(String[] args) throws MalformedURLException, IOException { DrawingUtils tt = new DrawingUtils(); BufferedImage j = tt.loadImageLocal("背景图路径"); BufferedImage k = tt.loadImageLocal("二维码路径"); tt.writeImageLocal("生成海报存放路径", tt.modifyImagetogeter(k, j, 175, 140)); //此处可重复屡次合成多张图片 //完成后便可上传对象存储 //filedel("C:\\Users\\Waitforyou\\Desktop\\img\\c1.jpg");//完成后删除本地文件 System.out.println("success"); } }
附件:裁剪、缩放图片工具类小程序
/** * Copyright © 2019 eSunny Info. Tech Ltd. All rights reserved. * * 功能描述: * @Package: com.ruoyi.web.core.config * @author: Waitforyou * @date: 2019年6月22日 下午9:48:39 */ package com.ruoyi.web.pay.config; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; /** * 裁剪、缩放图片工具类 * @author WuHao 没有梦想-何须远方 */ public class ImgUtils { /** * 缩放图片方法 * @param srcImageFile 要缩放的图片路径 * @param result 缩放后的图片路径 * @param height 目标高度像素 * @param width 目标宽度像素 * @param bb 是否补白 */ public final static void scale(String srcImageFile, String result, int height, int width, boolean bb) { try { double ratio = 0.0; // 缩放比例 File f = new File(srcImageFile); BufferedImage bi = ImageIO.read(f); Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);//bi.SCALE_SMOOTH 选择图像平滑度比缩放速度具备更高优先级的图像缩放算法。 // 计算比例 if ((bi.getHeight() > height) || (bi.getWidth() > width)) { double ratioHeight = (new Integer(height)).doubleValue()/ bi.getHeight(); double ratioWhidth = (new Integer(width)).doubleValue()/ bi.getWidth(); if(ratioHeight>ratioWhidth){ ratio= ratioHeight; }else{ ratio= ratioWhidth; } AffineTransformOp op = new AffineTransformOp(AffineTransform//仿射转换 .getScaleInstance(ratio, ratio), null);//返回表示剪切变换的变换 itemp = op.filter(bi, null);//转换源 BufferedImage 并将结果存储在目标 BufferedImage 中。 } if (bb) {//补白 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//构造一个类型为预约义图像类型之一的 BufferedImage。 Graphics2D g = image.createGraphics();//建立一个 Graphics2D,能够将它绘制到此 BufferedImage 中。 g.setColor(Color.white);//控制颜色 g.fillRect(0, 0, width, height);// 使用 Graphics2D 上下文的设置,填充 Shape 的内部区域。 if (width == itemp.getWidth(null)) g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), Color.white, null); else g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), Color.white, null); g.dispose(); itemp = image; } ImageIO.write((BufferedImage) itemp, "JPEG", new File(result)); //输出压缩图片 } catch (IOException e) { e.printStackTrace(); } } /** * 裁剪图片方法 * @param bufferedImage 图像源 * @param startX 裁剪开始x坐标 * @param startY 裁剪开始y坐标 * @param endX 裁剪结束x坐标 * @param endY 裁剪结束y坐标 * @return */ public static BufferedImage cropImage(BufferedImage bufferedImage, int startX, int startY, int endX, int endY) { int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); if (startX == -1) { startX = 0; } if (startY == -1) { startY = 0; } if (endX == -1) { endX = width - 1; } if (endY == -1) { endY = height - 1; } BufferedImage result = new BufferedImage(endX - startX, endY - startY, 4); for (int x = startX; x < endX; ++x) { for (int y = startY; y < endY; ++y) { int rgb = bufferedImage.getRGB(x, y); result.setRGB(x - startX, y - startY, rgb); } } return result; } }