可根据实际情况进行修改

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
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;

/**
* 有关图片的工具类
*
* @author johnniang
*/
public class ImageUtils {

private ImageUtils() {
}

/**
* 合并图片,默认从右下角开始堆叠
*
* @param fgImage 前景图片,不能为空
* @param bgImage 背景图片,不能为空
* @param margin 边距,单位:px
* @return 合并后的图片
*/
public static BufferedImage overlay(BufferedImage fgImage, BufferedImage bgImage, int margin) {
Assert.notNull(fgImage, "foreground image must not be null");
Assert.notNull(bgImage, "background image must not be null");

int x = bgImage.getWidth() - fgImage.getWidth() - margin;
int y = bgImage.getHeight() - fgImage.getWidth() - margin;

return overlay(fgImage, bgImage, x, y);
}


/**
* 合并图片,默认从右下角开始堆叠
*
* @param fgImage 前景图片,不能为空
* @param bgImage 背景图片,不能为空
* @return 合并后的图片
*/
public static BufferedImage overlay(BufferedImage fgImage, BufferedImage bgImage) {
return overlay(fgImage, bgImage, 0);
}

/**
* 合并图片
*
* @param fgImage 前景图片,不能为空
* @param bgImage 背景图片,不能为空
* @return 返回合并后的图片
*/
public static BufferedImage overlay(BufferedImage fgImage, BufferedImage bgImage, int x, int y) {
Assert.notNull(fgImage, "foreground image must not be null");
Assert.notNull(bgImage, "background image must not be null");
Assert.isTrue(fgImage.getWidth() < bgImage.getWidth(),
"foreground image's width must less than background image");
Assert.isTrue(fgImage.getHeight() < bgImage.getHeight(),
"forground image's height must less than background image");

Graphics2D g = bgImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

// draw background image
g.drawImage(bgImage, 0, 0, null);

// draw foreground image
g.drawImage(fgImage, x, y, null);
g.dispose();

return bgImage;
}

/**
* 缩放图片
*
* @param image 原图片,不能为空
* @param zoomLevel 缩放倍数,不能小于0
* @return 返回缩放后的图片
*/
public static BufferedImage zoom(BufferedImage image, float zoomLevel) {
Assert.notNull(image, "image must not be null");
Assert.isTrue(zoomLevel > 0, "zoom level must not be less than 0");

int newImageWidth = (int) (image.getWidth() * zoomLevel);
int newImageHeight = (int) (image.getHeight() * zoomLevel);

BufferedImage newImage = new BufferedImage(newImageWidth, newImageHeight, image.getType());
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, newImageWidth, newImageHeight, null);
g.dispose();

return newImage;
}

/**
* 写入图片到指定位置
*
* @param image
* @param filepath
* @param extension
* @throws IOException
*/
public static void writeImage(BufferedImage image, String filepath, String extension) throws IOException {
File file = new File(filepath);

ImageIO.write(image, extension, file);
}

public static void writeImage(BufferedImage image, String formatName, OutputStream output) throws IOException {
ImageIO.write(image, formatName, output);
}

public static BufferedImage readImage(File file) throws IOException {
Assert.notNull(file, "file must not be null");

return ImageIO.read(file);
}

public static BufferedImage readImage(InputStream inputStream) throws IOException {
Assert.notNull(inputStream, "input stream must not be null");

return ImageIO.read(inputStream);
}

public static BufferedImage readImage(byte[] buf) throws IOException {
Assert.notNull(buf, "image byte array must not be null");

return ImageIO.read(new ByteArrayInputStream(buf));
}

/**
* 压缩图片
*
* @param originalImage 原始图片
* @param quantity 压缩质量(0-1),越小质量越差
* @return 返回新的图片
* @throws IOException 最后写入图片的时候可能出现异常
*/
public static BufferedImage compress(BufferedImage originalImage, float quantity) throws IOException {
Assert.notNull(originalImage, "original image must not be null");

Iterator<ImageWriter> imageWriterIterator = ImageIO.getImageWritersByFormatName("jpg");

try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputStream)) {

// 获取图片写入器
ImageWriter imageWriter = imageWriterIterator.next();

// 设置输出流
imageWriter.setOutput(imageOutputStream);

// 获取图片写入参数
ImageWriteParam param = imageWriter.getDefaultWriteParam();

if (param.canWriteCompressed()) {
// 设置压缩参数
param.setCompressionMode((ImageWriteParam.MODE_EXPLICIT));
param.setCompressionQuality(quantity);
}

// 正式写入压缩内容到输出流
imageWriter.write(null, new IIOImage(originalImage, null, null), param);

// 销毁图片写入器
imageWriter.dispose();

// 读取输出流到图片
return readImage(outputStream.toByteArray());
}
}
}