123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- package com.ruoyi.common.utils.file;
- import com.ruoyi.common.config.RuoYiConfig;
- import com.ruoyi.common.constant.Constants;
- import com.ruoyi.common.utils.StringUtils;
- import net.coobird.thumbnailator.Thumbnails;
- import org.apache.poi.util.IOUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.imageio.ImageIO;
- import java.awt.*;
- import java.awt.image.BufferedImage;
- import java.io.*;
- import java.net.URL;
- import java.net.URLConnection;
- import java.util.Arrays;
- /**
- * 图片处理工具类
- *
- * @author ruoyi
- */
- public class ImageUtils {
- private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);
- public static byte[] getImage(String imagePath) {
- InputStream is = getFile(imagePath);
- try {
- return IOUtils.toByteArray(is);
- } catch (Exception e) {
- log.error("图片加载异常 {}", e);
- return null;
- } finally {
- IOUtils.closeQuietly(is);
- }
- }
- public static InputStream getFile(String imagePath) {
- try {
- byte[] result = readFile(imagePath);
- result = Arrays.copyOf(result, result.length);
- return new ByteArrayInputStream(result);
- } catch (Exception e) {
- log.error("获取图片异常 {}", e);
- }
- return null;
- }
- /**
- * 读取文件为字节数据
- *
- * @param url 地址
- * @return 字节数据
- */
- public static byte[] readFile(String url) {
- InputStream in = null;
- try {
- if (url.startsWith("http")) {
- // 网络地址
- URL urlObj = new URL(url);
- URLConnection urlConnection = urlObj.openConnection();
- urlConnection.setConnectTimeout(30 * 1000);
- urlConnection.setReadTimeout(60 * 1000);
- urlConnection.setDoInput(true);
- in = urlConnection.getInputStream();
- } else {
- // 本机地址
- String localPath = RuoYiConfig.getProfile();
- String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX);
- in = new FileInputStream(downloadPath);
- }
- return IOUtils.toByteArray(in);
- } catch (Exception e) {
- log.error("获取文件路径异常 {}", e);
- return null;
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
- /**
- * 添加图片水印
- *
- * @param sourceFile 文件源路径
- * @param destFile 文件路径
- * @param watermarkText1 水印信息上
- * @param watermarkText2 水印信息下
- * @throws Exception 异常
- */
- public static void addWatermark(File sourceFile, File destFile, String watermarkText1, String watermarkText2) throws Exception {
- // 读取图片
- BufferedImage image = ImageIO.read(sourceFile);
- // 获取图片宽高
- int width = image.getWidth();
- int height = image.getHeight();
- // 创建 Graphics2D 对象
- Graphics2D g2d = (Graphics2D) image.getGraphics();
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- // 根据图片大小调整字体大小
- int fontSize = Math.max(width, height) / 40; // 字体大小为图片较大边长的 1/20
- g2d.setFont(new Font("SimHei", Font.BOLD, fontSize));
- // g2d.setColor(new Color(255, 255, 255, 128)); // 白色半透明
- // 计算水印文本宽高
- FontMetrics fontMetrics = g2d.getFontMetrics();
- // 第一行水印的宽高
- int textWidth1 = fontMetrics.stringWidth(watermarkText1);
- int textHeight = fontMetrics.getHeight(); // 每行的高度
- // 第二行水印的宽度
- int textWidth2 = fontMetrics.stringWidth(watermarkText2);
- // 计算水印的位置(右下角,分两行)
- int padding = width / 50; // 边距
- int x1 = width - textWidth1 - padding; // 第一行水平位置
- int x2 = width - textWidth2 - padding; // 第二行水平位置
- int y1 = height - textHeight - padding; // 第一行垂直位置
- int y2 = height - padding; // 第二行垂直位置
- // 分析水印区域的背景颜色(取样水印区域的平均颜色)
- Color averageColor = getAverageColor(image, x1, y1 - textHeight, textWidth1, textHeight + (y2 - y1));
- // 判断背景颜色是否浅色或深色
- Color watermarkColor = isLightColor(averageColor) ? new Color(0, 0, 0, 180) : new Color(255, 255, 255, 128);
- // 设置水印颜色
- g2d.setColor(watermarkColor);
- // 绘制两行水印
- g2d.drawString(watermarkText1, x1, y1);
- g2d.drawString(watermarkText2, x2, y2);
- g2d.dispose();
- // 保存处理后的图片
- // ImageIO.write(image, "jpg", destFile);
- String format = sourceFile.getName().substring(sourceFile.getName().lastIndexOf(".") + 1);
- ImageIO.write(image, format, destFile);
- }
- /**
- * 判断颜色是否为浅色
- *
- * @param color 颜色
- * @return true 表示浅色,false 表示深色
- */
- private static boolean isLightColor(Color color) {
- // 使用加权公式计算亮度
- double brightness = (color.getRed() * 0.299 + color.getGreen() * 0.587 + color.getBlue() * 0.114);
- return brightness > 128; // 亮度大于128为浅色
- }
- /**
- * 获取指定区域的平均颜色
- *
- * @param image 图片
- * @param x 起始横坐标
- * @param y 起始纵坐标
- * @param width 区域宽度
- * @param height 区域高度
- * @return 平均颜色
- */
- private static Color getAverageColor(BufferedImage image, int x, int y, int width, int height) {
- int r = 0, g = 0, b = 0, count = 0;
- for (int i = x; i < x + width && i < image.getWidth(); i++) {
- for (int j = y; j < y + height && j < image.getHeight(); j++) {
- Color pixelColor = new Color(image.getRGB(i, j));
- r += pixelColor.getRed();
- g += pixelColor.getGreen();
- b += pixelColor.getBlue();
- count++;
- }
- }
- return new Color(r / count, g / count, b / count);
- }
- /**
- * 生成缩略图并进行压缩
- *
- * @param originalImagePath 原始图片路径
- * @param thumbImagePath 缩略图保存路径
- * @param width 缩略图宽度
- * @param height 缩略图高度
- * @param quality 压缩质量,范围0-1,值越低压缩越厉害
- * @throws IOException IO异常
- */
- public static void compressAndGenerateThumbnail(String originalImagePath, String thumbImagePath, int width, int height, float quality) throws IOException {
- // 压缩图片并生成缩略图
- Thumbnails.of(new File(originalImagePath))
- .size(width, height) // 设置缩略图的宽高
- .outputQuality(quality) // 设置图片压缩质量
- .toFile(new File(thumbImagePath)); // 输出文件
- }
- }
|