rain
2024-06-20 3904fbdccb96a9b1b4f919d18505d5ebb8ef976a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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;
 
import static com.dji.sample.territory.utils.ImgZipUtil.compressImageAndGetFile;
 
@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"); // 替换为你的字体文件路径
        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));
        }
    }
}