package com.dji.sample.territory.utils;
|
|
import org.springframework.stereotype.Component;
|
|
import javax.imageio.ImageIO;
|
import java.awt.*;
|
import java.awt.geom.AffineTransform;
|
import java.awt.image.BufferedImage;
|
import java.io.File;
|
import java.io.IOException;
|
import java.text.SimpleDateFormat;
|
import java.util.Date;
|
@Component
|
public class WaterMarkUtil {
|
|
/**
|
* 将图片加上水印并压缩
|
*
|
* @param file
|
* @param pssj
|
* @param lat
|
* @param lng
|
* @return 添加水印并压缩后的图片文件。
|
* @throws IOException 如果读取或保存图片失败。
|
*/
|
public static File addWatermark(File file, Long pssj, Double lat, Double lng, Double angles) throws IOException, FontFormatException {
|
double anglses = convertAngle(angles);
|
String angel = angle(anglses);
|
Long timestamp = pssj; // 例如:Unix 时间戳(以秒为单位)
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
String sd = sdf.format(new Date(Long.parseLong(String.valueOf(timestamp))));
|
File originalImageFile = new File(file.toURI());
|
BufferedImage originalImage;
|
try {
|
originalImage = ImageIO.read(originalImageFile);
|
} catch (IOException e) {
|
throw new IllegalArgumentException("读取图片失败" + e.getMessage());
|
}
|
|
// 创建 Graphics2D 对象以在图像上绘制水印
|
Graphics2D g2d = originalImage.createGraphics();
|
|
// 设置水印文字 "江西调查云"
|
String watermarkText = "江西调查云";
|
float alpha = 0.8f; // 设置透明度为 0.7
|
AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
|
g2d.setComposite(alphaComposite);
|
g2d.setFont(new Font("宋体", Font.BOLD, 150)); // 使用宋体字体
|
FontMetrics fms = g2d.getFontMetrics();
|
int textHeights = fms.getHeight();
|
|
// 设置水印位置(左居中)
|
int x1 = 600; // 左边距离图片左边缘的距离
|
int y1 = (originalImage.getHeight() - textHeights) - 800; // 垂直居中
|
// 旋转35度角
|
double angle = Math.toRadians(50);
|
AffineTransform at = AffineTransform.getRotateInstance(angle, x1, y1);
|
g2d.setTransform(at);
|
// 绘制左上角旋转水印文字
|
g2d.drawString(watermarkText, x1, y1);
|
alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);
|
g2d.setComposite(alphaComposite);
|
String extraInfo = String.format("Lon:%.7f Lat:%.7f\n%s %s", lng, lat, angel, sd);
|
// File fontFile = new File("/usr/share/fonts/MiSans-Normal.ttf"); // 替换为你的字体文件路径
|
File fontFile = new File("src/main/resources/MiSans-Normal.ttf"); // 替换为你的字体文件路径
|
Font customFont = Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(36.00F);
|
// 注册字体
|
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
ge.registerFont(customFont);
|
g2d.setFont(customFont);
|
|
// 计算文本宽度和高度
|
FontMetrics fm = g2d.getFontMetrics();
|
int textWidth = fm.stringWidth(extraInfo);
|
int textHeight = fm.getHeight();
|
// 恢复坐标系到正常状态(不旋转)
|
g2d.setTransform(new AffineTransform());
|
// 设置文本位置(右下角)
|
int x2 = originalImage.getWidth() - textWidth - 30; // 右对齐的 x 坐标
|
int y2 = originalImage.getHeight() - textHeight - 30; // 最底部位置 y 坐标
|
|
|
int rectX = originalImage.getWidth() - textWidth + 490;
|
int rectY = originalImage.getHeight() - textHeight - 15;
|
// 绘制半透明黑色背景矩形
|
Color semiTransparentColor = new Color(0, 0, 0, 156); // 0-255 的 alpha 值,0 表示完全透明,255 表示完全不透明
|
g2d.setColor(semiTransparentColor);
|
g2d.fillRect(rectX, rectY, textWidth, textHeight - 6);
|
|
int rectXs = originalImage.getWidth() - textWidth + 420;
|
int rectYs = originalImage.getHeight() - textHeight - 62;
|
// 绘制半透明黑色背景矩形
|
g2d.setColor(semiTransparentColor);
|
g2d.fillRect(rectXs, rectYs, textWidth, textHeight - 10);
|
|
// int rectXw = originalImage.getWidth() - textWidth +1510 ;
|
// int rectYw = originalImage.getHeight() - textHeight -124;
|
//
|
// // 绘制半透明黑色背景矩形
|
// g2d.setColor(semiTransparentColor);
|
// g2d.fillRect(rectXw, rectYw, textWidth, textHeight-6);
|
// 绘制文本信息
|
String[] lines = extraInfo.split("\n");
|
for (String line : lines) {
|
g2d.setColor(Color.WHITE);
|
// 计算每行文本的宽度
|
int lineWidth = fm.stringWidth(line);
|
// 将文本的起始位置设置为图像宽度减去文本的宽度
|
g2d.drawString(line, x2 + textWidth - lineWidth, y2);
|
y2 += g2d.getFontMetrics().getHeight(); // 增加行高
|
}
|
// 释放 Graphics2D 对象
|
g2d.dispose();
|
// 保存添加水印后的图片
|
File outputFile = File.createTempFile("mark", ".jpg");
|
|
try {
|
ImageIO.write(originalImage, "jpg", outputFile); // 将图像写入临时文件
|
} catch (IOException e) {
|
throw new IllegalArgumentException("水印图片保存失败");
|
}
|
|
return outputFile; // 返回保存的文件对象
|
}
|
|
public static String angle(double angle) {
|
if (angle > 0 && angle < 45) {
|
return "北偏东";
|
}
|
if (angle > 45 && angle < 90) {
|
return "东偏北";
|
}
|
if (angle > 90 && angle < 135) {
|
return "东偏南";
|
}
|
if (angle > 135 && angle < 180) {
|
return "南偏东";
|
}
|
if (angle > 315 && angle < 360) {
|
return "北偏西";
|
}
|
if (angle > 270 && angle < 315) {
|
return "西偏北";
|
}
|
if (angle > 225 && angle < 270) {
|
return "西偏南";
|
}
|
if (angle > 180 && angle < 225) {
|
return "南偏西";
|
}
|
if (angle == 45) {
|
return "东北";
|
}
|
if (angle == 135) {
|
return "东南";
|
}
|
if (angle == 225) {
|
return "西南";
|
}
|
if (angle == 315) {
|
return "西北";
|
}
|
if (angle == 0 || angle == 360) {
|
return "正北";
|
}
|
if (angle == 90) {
|
return "正东";
|
}
|
if (angle == 180) {
|
return "正南";
|
}
|
if (angle == 270) {
|
return "正西";
|
}
|
return "未知";
|
}
|
|
public static double convertAngle(double angle) {
|
// 处理负数角度,将其转换为正数
|
if (angle < 0) {
|
angle += 360;
|
}
|
return angle;
|
}
|
|
public static void main(String[] args) {
|
// 测试不同的输入角度
|
double[] testAngles = {25};
|
for (double angle : testAngles) {
|
System.out.printf("输入角度: %.1f, 转换后的方位角: %.1f\n", angle, convertAngle(angle));
|
}
|
}
|
}
|