Efficient Image Compression and Resizing in Java with Spring Boot

// application.yml or properties
file.upload.path: /var/uploads
@RestController
public class ImageUploadController {

    @Value("${file.upload.path}")
    private String uploadDirectory;

    @PostMapping("/upload")
    public void handleUpload(@RequestParam("file") MultipartFile source) throws IOException {
        // Save original to target location
        File original = new File(uploadDirectory, source.getOriginalFilename());
        source.transferTo(original);

        // Extract file parts
        String fullName = source.getOriginalFilename();
        String baseName = fullName.substring(0, fullName.lastIndexOf('.'));
        String extension = fullName.substring(fullName.lastIndexOf('.') + 1).toLowerCase();

        // Paths for processed outputs
        File resizedOutput = new File(uploadDirectory, "resized_" + fullName);
        File convertedOutput = new File(uploadDirectory, "converted_" + baseName + ".jpg");

        long start = System.currentTimeMillis();

        // Image processing steps go here
        // e.g. scale, compress, or convert

        long end = System.currentTimeMillis();
        System.out.println("Processing took " + (end - start) + " ms");
    }
}

Using Hutool

Maven dependency:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.4.1</version>
</dependency>

Resize by Scaling

ImgUtil.scale(
    FileUtil.file(original),
    FileUtil.file(resizedOutput),
    0.5f // scaling factor
);
Format Original Size After Scale Duration Scale Factor
JPG 951 KB 155 KB ~759 ms 0.5
PNG 2.00 MB 1.15 MB ~867 ms 0.5

Cropping

Rectangle(x, y, width, height) defines the region from the top-left corner.

ImgUtil.cut(
    FileUtil.file(original),
    FileUtil.file(resizedOutput),
    new Rectangle(0, 0, 200, 200) // example rectangle
);

Format Conversion

Supports GIF→JPG, GIF→PNG, PNG→JPG, and BMP→PNG.

ImgUtil.convert(
    FileUtil.file(original),
    FileUtil.file(convertedOutput)
);

Quality Compression

Only JPEG files support quality adjustment directly; other formats get converted to JPEG first.

if ("jpg".equals(extension) || "jpeg".equals(extension)) {
    Img.from(FileUtil.file(original))
       .setQuality(0.5f)
       .write(FileUtil.file(resizedOutput));
} else {
    Img.from(FileUtil.file(original))
       .setQuality(0.5f)
       .write(FileUtil.file(convertedOutput));
}
Format Original Size Compressed Size Duration Quality
JPG 951 KB 312 KB ~420 ms 0.5
PNG 2.00 MB 352 KB ~1139 ms 0.5

Using Thumbnails

Maven dependency:

<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>[0.4, 0.5)</version>
</dependency>

Quality-Based Compresssion

Reducing output quality to shrink file size.

Thumbnails.of(original)
    .scale(1.0)
    .outputQuality(0.5)
    .toFile(convertedOutput);
Format Orgiinal Size Compressed Size Duration Quality
JPG 951 KB 312 KB ~463 ms 0.5
PNG 2.00 MB 352 KB ~1692 ms 0.5

Simpler variant without quality parameter:

Thumbnails.of(original)
    .scale(1.0)
    .toFile(convertedOutput);
Format Original Size Result Size Duration
JPG 951 KB 591 KB ~540 ms
PNG 2.00 MB 400 KB ~1769 ms

Scaling (Resize)

Thumbnails.of(original)
    .scale(0.5)
    .toFile(convertedOutput);
Format Original Size Scaled Size Duration Scale
JPG 951 KB 136 KB ~428 ms 0.5
PNG 2.00 MB 122 KB ~1005 ms 0.5

All measured times may vary by ±200 ms depending on disk speed and system load.

Tags: java Image Processing compression Hutool Thumbnails

Posted on Fri, 26 Jun 2026 17:18:21 +0000 by Broniukas