Convert picture to customized size

Main method

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
public static BufferedImage imageConvert(InputStream inputStream, Integer limit) throws IOException {
if (inputStream == null || limit == null) return null;
// init
BufferedImage inputImage = ImageIO.read(inputStream);
int size = getImageSize(inputImage);
if (size <= 0 || inputImage == null) return null;

// loop reduce pixel
while (size > imgLimit) {
// calculate edge shrink propotion
// minus .05 improve convert speed
double rate = (double)imgLimit/size - .05;
// if origin is 20 times than limit, rate may little than 0
// set ten times smaller than origin as default
if (rate < 0) rate = .1;
rate = Math.sqrt(rate);

int width = (int)(inputImage.getWidth(null) * rate);
int height = (int)(inputImage.getHeight(null) * rate);
BufferedImage outputImage = imageCompress(inputImage, width, height);
inputImage = outputImage;

// recalculate
size = getImageSize(inputImage);
}
return inputImage;
}

Assistant method

1
2
3
4
5
6
7
public static int getImageSize(BufferedImage img) throws IOException {
ByteArrayOutputStream byteOS = new ByteArrayOutputStream();
ImageIO.write(img, "jpg", byteOS);
int size = byteOS.size();
byteOS.close();
return size;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public static BufferedImage imageCompress(Image img, int w, int h) throws IOException {
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB );
// redraw converted graph
image.getGraphics().drawImage(img, 0, 0, w, h, null);

ByteArrayOutputStream byteOS = new ByteArrayOutputStream(256);
ImageIO.write(image, "jpg", byteOS);
ByteArrayInputStream byteIS = new ByteArrayInputStream(byteOS.toByteArray());
BufferedImage product = ImageIO.read(byteIS);
byteOS.close();
byteIS.close();
return product;
}

Summary

Use memory to loop picture may cause leak problem.
Use 3th part software maybe a better choice? like ffmpeg.

https://www.cnblogs.com/shoufengwei/p/8526105.html