需求:将从数据库中获取出来的图片添加水印展示在app端
先从数据库获取图片,使用了文件服务器minio
1. 拿到图片的链接地址如下:
http://47.108.116.186:9500/ukt-admin/a9f1ebe1-f605-4ae5-8587-313ac59edaf6
2. 根据图片的链接地址下载图片 代码工具类如下:
package com.ruoyi.business.utils;
import org.springframework.beans.factory.annotation.Value;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
/**
* @description: 根据文件链接地址下载文件
* @author: wcb
* @date: 2021/8/3 10:47
*/
public class DownloadFile {
@Value("${dbv.tbf}")
private String tbf;
/**
* 根据链接地址下载文件
* @param downloadUrl 文件链接地址
* @param path 下载存放文件地址 + 文件名
*/
public String downloadA(String downloadUrl,String path) {
//水印内容
String font = "www.uktian.com";
URL url = null;
DataInputStream dataInputStream = null;
FileOutputStream fileOutputStream = null;
try {
url = new URL(downloadUrl);
dataInputStream = new DataInputStream(url.openStream());
fileOutputStream = new FileOutputStream(new File(path));
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = dataInputStream.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
fileOutputStream.write(output.toByteArray());
String timestamp = String.valueOf(Date.parse(String.valueOf(new Date())));
String uuid = new WaterMark().waterPress(path,
tbf+"营业执照"+timestamp+".jpg", Color.gray, 50, font);
return uuid;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* @param downloadUrl 文件链接地址
* @param filename 保存文件名
* @param filePath 保存文件路径
*/
private static void downloadB(String downloadUrl, String filename, String filePath) {
URL url = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
url = new URL(downloadUrl);
// 打开连接
URLConnection con = url.openConnection();
// 请求超时:5s
con.setConnectTimeout(5 * 1000);
inputStream = con.getInputStream();
byte[] bytes = new byte[1024];
// 读取到的数据长度
int length;
File savePath = new File(filePath);
if (!savePath.exists()) {
// 如果不存在当前文件夹,则创建该文件夹
boolean mkdir = savePath.mkdirs();
if (!mkdir) {
System.out.println("创建文件夹失败");
return;
}
}
outputStream = new FileOutputStream(savePath.getPath() + "\\" + filename);
// 读取
while ((length = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
下载完成后 添加水印 如下:
package com.ruoyi.business.utils;
import com.ruoyi.business.config.MinioConfig;
import com.ruoyi.business.controller.TestFileUploadController;
import io.minio.MinioClient;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.UUID;
/**
* 满屏水印
* @version 1.0
* @author: wcb
* @date: 2021-08-03 10:11
*/
public class WaterMark {
@Autowired
private MinioConfig minioConfig;
/**
* 水印之间的横向间隔
*/
private static final int XMOVE = 80;
/**
* 水印之间的纵向间隔
*/
private static final int YMOVE = 80;
/**
* 图片添加水印
*
* @param outImgPath 添加水印后图片输出路径
* @param markContentColor 水印文字的颜色
* @param fontSize 文字大小
* @param waterMarkContent 水印的文字,多排水印请使用"||"分割
* @param srcImgPath 需要添加水印的图片的路径
*/
@SneakyThrows
public String waterPress(String srcImgPath, String outImgPath, Color markContentColor, int fontSize, String waterMarkContent) {
try {
String[] waterMarkContents = waterMarkContent.split("\\|\\|");
// 读取原图片信息
File srcImgFile = new File(srcImgPath);
Image srcImg = ImageIO.read(srcImgFile);
// 原图宽度
int srcImgWidth = srcImg.getWidth(null);
// 原图高度
int srcImgHeight = srcImg.getHeight(null);
// 加水印
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
// 得到画笔对象
Graphics2D g = bufImg.createGraphics();
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
// Font font = new Font("Courier New", Font.PLAIN, 12);
// 字体
Font font = new Font("宋体", Font.PLAIN, fontSize);
// 根据图片的背景设置水印颜色
g.setColor(markContentColor);
// 设置水印文字字体
g.setFont(font);
// 设置水印旋转
g.rotate(Math.toRadians(-45), (double) bufImg.getWidth() / 2, (double) bufImg.getHeight() / 2);
// 获取其中最长的文字水印的大小
int maxLen = 0;
int maxHigh = 0;
for (int i = 0; i < waterMarkContents.length; i++) {
waterMarkContent = waterMarkContents[i];
int fontlen = getWatermarkLength(waterMarkContent, g);
if (fontlen >= maxLen) {
maxLen = fontlen;
}
maxHigh = maxHigh + (i + 1) * fontSize + 10;
break;
}
// 文字长度相对于图片宽度应该有多少行
int line = srcImgWidth * 2 / maxLen;
int co = srcImgHeight * 2 / maxHigh;
int yz = 0;
// 填充Y轴方向
for (int a = 0; a < co; a++) {
int t = 0;
for (int j = 0; j < waterMarkContents.length; j++) {
waterMarkContent = waterMarkContents[j];
int y = (j + 1) * fontSize + 10 + t;
// 文字叠加,自动换行叠加,注意符号
int tempX = -srcImgWidth / 2;
int tempY = -srcImgHeight / 2 + y + yz;
// 单字符长度
int tempCharLen = 0;
// 单行字符总长度临时计算
int tempLineLen = 0;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < waterMarkContent.length(); i++) {
char tempChar = waterMarkContent.charAt(i);
tempCharLen = getCharLen(tempChar, g);
tempLineLen += tempCharLen;
// 和图片的长度进行对应的比较操作
if (tempLineLen >= srcImgWidth) {
// 长度已经满一行,进行文字叠加
g.drawString(sb.toString(), tempX, tempY);
t = t + fontSize;
// 清空内容,重新追加
sb.delete(0, sb.length());
tempY += fontSize;
tempLineLen = 0;
}
// 追加字符
sb.append(tempChar);
}
// 填充X轴
for (int z = 0; z < line; z++) {
// 最后叠加余下的文字
g.drawString(sb.toString(), tempX, tempY);
tempX = tempX + maxLen + XMOVE;
}
}
yz = yz + maxHigh + YMOVE;
}
g.dispose();
String uuid = UUID.randomUUID().toString();
// 输出图片
FileOutputStream outImgStream = new FileOutputStream(outImgPath);
InputStream inputStream = new FileInputStream(outImgPath);
ImageIO.write(bufImg, "jpg", outImgStream);
outImgStream.flush();
outImgStream.close();
System.out.println("打印成功");
//调用上传接口
MinioClient minioClient = new MinioClient("http://47.108.116.186:9500","minioadmin","minioadmin");
minioClient.putObject("ukt-admin", uuid, inputStream, inputStream.available(), "image/jpeg");
System.out.println(uuid);
return uuid;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public int getCharLen(char c, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charWidth(c);
}
/**
* 获取水印文字总长度
*
* @paramwaterMarkContent水印的文字
* @paramg
* @return水印文字总长度
*/
public int getWatermarkLength(String waterMarkContent, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
}
// public static void main(String[] args) {
// // 原图位置, 输出图片位置, 水印文字颜色, 水印文字
// String font = "www.uktian.com";
// new WaterMark().waterPress("C:/Users/Administrator/Pictures/Saved Pictures/营业执照副本.jpg",
// "C:/Users/Administrator/Pictures/Saved Pictures/营业执照副本-测试水印.jpg", Color.gray, 30, font);
// }
}
查询代码中直接调用下载图片工具类
代码:
String uuid = new DownloadFile().downloadA(fileService.getFileUrl(iaFiles.getUuid()),tbf+"营业执照"+timestamp+".jpg");
最后再拼接返回图片连接,记住在下载图片和添加水印后需要返回一个UUID,同时为了能过预览图片,需要将图片上传到文件服务器
还有一个不要忘记了,我们在下载图片的时候需要创建一个临时存放图片的位置,这个位置不能写死在代码中,最好是配置在配置文件中,然后从方法中区获取配置文件的路径,如下:
配置文件:
引用配置文件
@Value("${dbv.tbf}")
private String tbf;
使用文件路径:
最好图片显示额效果图如下
以上为个人笔记,分享出来,大家一起参考,有不到之处请多多指教