I need to compress every image that is larger than 500 kbytes. So, i'm trying to create a code that will test every compression quality until i get <= 500 kb, then i'll have the best quality with the lowest length.
My biggest problem here is that writer method from ImageWriter appends my new image to the old. So, if i have a 600kb image and write a new one with low quality, i'll have 600kb + probably 500kb (size of the new image) in the same .jpg file and with a low quality.
My code:
public byte[] imageCompressor(String filePath, String newFileName, String formatName) throws IOException {
File input = new File(filePath);
BufferedImage image = ImageIO.read(input);
File compressedImageFile = new File(newFileName);
String compressedWithFormat = compressedImageFile + "." + formatName;
OutputStream os = new FileOutputStream(compressedWithFormat);
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
ImageWriter writer = (ImageWriter) writers.next();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(os);
writer.setOutput(ImageIO.createImageOutputStream(baos));
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
writer.write(null, new IIOImage(image, null, null), param);
float contador = 1f;
while (imageSizeChecker(compressedWithFormat) > 500) {
param.setCompressionQuality(contador -= 0.09f); // Change the quality value you prefer
writer.write(null, new IIOImage(image, null, null), param);
System.out.println(imageSizeChecker(compressedWithFormat));
writer.dispose();
}
writer.dispose();
return baos.toByteArray();
}
public Long imageSizeChecker(String filePath) {
File insertFile = new File(filePath);
Long fileSize = insertFile.length() / 1024;
return fileSize;
}
Also, i want to return the image in a byte array (as it follows), and i'm trying to send the image file on the parameter as a byte array (replacing String filepath for byte[] filepath)