第一步:授权获取小程序二维码
https://blog.csdn.net/weixin_37545129/article/details/88699623
第二步:准备好二维码背景图存放到本地文件夹中
第三步:开始绘图
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;
}
}