xiangpei
8 天以前 56224037cde5a381dbdce941bfc3a4f555584e3b
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
package cn.lili.modules.verification;
 
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
 
/**
 * ImageUtil
 *
 * @author Chopper
 * @version v1.0
 * 2020-11-17 14:50
 */
public class ImageUtil {
 
    /**
     * 添加水印
     *
     * @param oriImage 原图
     * @param text     文字
     * @throws IOException 流操作异常
     */
    public static void addWatermark(BufferedImage oriImage, String text) {
        Graphics2D graphics2D = oriImage.createGraphics();
        //设置水印文字颜色
        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        //设置水印文字Font
        graphics2D.setColor(Color.black);
        //设置水印文字透明度
        graphics2D.setFont(new Font("宋体", Font.BOLD, 30));
        //第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
        graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.4f));
        graphics2D.drawString(text, 10, 40);
        graphics2D.dispose();
    }
 
 
    /**
     * 干扰图
     *
     * @param oriImage      原图
     * @param templateImage 模板图
     * @param x             随机扣取坐标X
     * @param y             随机扣取坐标y
     */
    public static void interfereTemplate(BufferedImage oriImage, BufferedImage templateImage,
                                         int x, int y) {
        //临时数组遍历用于高斯模糊存周边像素值
        int[][] matrix = new int[3][3];
        int[] values = new int[9];
 
        int xLength = templateImage.getWidth();
        int yLength = templateImage.getHeight();
        //模板图像宽度
        for (int i = 0; i < xLength; i++) {
            //模板图片高度
            for (int j = 0; j < yLength; j++) {
                //如果模板图像当前像素点不是透明色 copy源文件信息到目标图片中
                int rgb = templateImage.getRGB(i, j);
                if (rgb < 0) {
                    //抠图区域高斯模糊
                    readPixel(oriImage, x + i, y + j, values);
                    fillMatrix(matrix, values);
                    oriImage.setRGB(x + i, y + j, avgMatrix(matrix));
                }
 
                //防止数组越界判断
                if (i == (xLength - 1) || j == (yLength - 1)) {
                    continue;
                }
                int rightRgb = templateImage.getRGB(i + 1, j);
                int downRgb = templateImage.getRGB(i, j + 1);
                //描边处理,,取带像素和无像素的界点,判断该点是不是临界轮廓点,如果是设置该坐标像素是白色
                boolean rgbImage = ((rgb >= 0 && rightRgb < 0)
                        || (rgb < 0 && rightRgb >= 0)
                        || (rgb >= 0 && downRgb < 0)
                        || (rgb < 0 && downRgb >= 0));
            }
        }
    }
 
    /**
     * @param oriImage      原图
     * @param templateImage 模板图
     * @param newImage      新抠出的小图
     * @param x             随机扣取坐标X
     * @param y             随机扣取坐标y
     */
    public static void cutByTemplate(BufferedImage oriImage, BufferedImage templateImage, BufferedImage newImage,
                                     int x, int y) {
        //临时数组遍历用于高斯模糊存周边像素值
        int[][] matrix = new int[3][3];
        int[] values = new int[9];
 
        int xLength = templateImage.getWidth();
        int yLength = templateImage.getHeight();
        //模板图像宽度
        for (int i = 0; i < xLength; i++) {
            //模板图片高度
            for (int j = 0; j < yLength; j++) {
                //如果模板图像当前像素点不是透明色 copy源文件信息到目标图片中
                int rgb = templateImage.getRGB(i, j);
                if (rgb < 0) {
                    newImage.setRGB(i, j, oriImage.getRGB(x + i, y + j));
 
                    //抠图区域高斯模糊
                    readPixel(oriImage, x + i, y + j, values);
                    fillMatrix(matrix, values);
                    oriImage.setRGB(x + i, y + j, avgMatrix(matrix));
                }
 
                //防止数组越界判断
                if (i == (xLength - 1) || j == (yLength - 1)) {
                    continue;
                }
                int rightRgb = templateImage.getRGB(i + 1, j);
                int downRgb = templateImage.getRGB(i, j + 1);
                //描边处理,,取带像素和无像素的界点,判断该点是不是临界轮廓点,如果是设置该坐标像素是白色
                boolean rgbImage = ((rgb >= 0 && rightRgb < 0)
                        || (rgb < 0 && rightRgb >= 0)
                        || (rgb >= 0 && downRgb < 0)
                        || (rgb < 0 && downRgb >= 0));
 
                if (rgbImage) {
                    newImage.setRGB(i, j, Color.GRAY.getRGB());
                }
            }
        }
    }
 
    public static void readPixel(BufferedImage img, int x, int y, int[] pixels) {
        int xStart = x - 1;
        int yStart = y - 1;
        int current = 0;
        for (int i = xStart; i < 3 + xStart; i++) {
            for (int j = yStart; j < 3 + yStart; j++) {
                int tx = i;
                if (tx < 0) {
                    tx = -tx;
 
                } else if (tx >= img.getWidth()) {
                    tx = x;
                }
                int ty = j;
                if (ty < 0) {
                    ty = -ty;
                } else if (ty >= img.getHeight()) {
                    ty = y;
                }
                pixels[current++] = img.getRGB(tx, ty);
 
            }
        }
    }
 
    public static void fillMatrix(int[][] matrix, int[] values) {
        int filled = 0;
        for (int[] x : matrix) {
            for (int j = 0; j < x.length; j++) {
                x[j] = values[filled++];
            }
        }
    }
 
    public static int avgMatrix(int[][] matrix) {
        int r = 0;
        int g = 0;
        int b = 0;
        for (int[] x : matrix) {
            for (int j = 0; j < x.length; j++) {
                if (j == 1) {
                    continue;
                }
                Color c = new Color(x[j]);
                r += c.getRed();
                g += c.getGreen();
                b += c.getBlue();
            }
        }
        return new Color(r / 8, g / 8, b / 8).getRGB();
    }
}