Spring Boot Upload and Resize Images with Imgscalr
Tags: Upload Resize Image Imgscalr FilenameUtils Scalr BufferedImage ImageIO MultipartFile RedirectAttributes
Introduction
In this Spring Boot tutorial we learn how to implement a Spring Boot web application that allows users to upload and resize image files by using Spring Boot Web, Thymeleaf, Apache Commons IO and Imgscalr libraries.
Create New Spring Boot Web Project
Open Spring Tool Suite IDE, select menu File > New > Spring Starter Project.
On the New Spring Starter Project popup input new project information as below and click Next.
- Name: spring-boot-upload-resize
- Group: dev.simplesolution
- Artifact: spring-boot-upload-resize
- Version: 1.0.0
- Description: Spring Boot Web Upload and Resize
- Package: dev.simplesolution.uploadresize
On the New Spring Starter Project Dependencies popup choose dependencies as below and click Next.
- Thymeleaf
- Spring Web
Keep the information on the next popup as default and click Finish.
You can also creating new Spring Boot project using Spring initializr online tool at start.spring.io
Add Apache Commons IO and Imgscalr libraries to the project
In this step we set up the Apache Commons IO and Imgscalr libraries for the Spring Boot web project.
To use the Apache Commons IO and Imgscalr libraries in the Gradle build project, add the following dependency into the build.gradle file.
implementation 'org.imgscalr:imgscalr-lib:4.2'
implementation 'commons-io:commons-io:2.9.0'
The final build.gradle file is below.
build.gradle
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'dev.simplesolution'
version = '1.0.0'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.imgscalr:imgscalr-lib:4.2'
implementation 'commons-io:commons-io:2.9.0'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
To use the Apache Commons IO and Imgscalr libraries in the Maven build project, add the following dependency into the pom.xml file.
<dependency>
<groupId>org.imgscalr</groupId>
<artifactId>imgscalr-lib</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.9.0</version>
</dependency>
The final pom.xml file is below.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>dev.simplesolution</groupId>
<artifactId>spring-boot-upload-resize</artifactId>
<version>1.0.0</version>
<name>spring-boot-upload-resize</name>
<description>Spring Boot Web Upload and Resize</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.imgscalr</groupId>
<artifactId>imgscalr-lib</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Add Application Configurations to application.properties
At this step we add the below configuration to the config file at /src/main/resources/application.properties
application.properties
spring.servlet.multipart.max-file-size=16MB
spring.servlet.multipart.max-request-size=16MB
server.servlet.session.tracking-modes=cookie
image.folder=D:\\SimpleSolution\\Images
image.size=400
- spring.servlet.multipart.max-file-size to set the maximum upload file size.
- spring.servlet.multipart.max-request-size to set the maximum request size.
- server.servlet.session.tracking-modes to allow application transfer session id via cookie.
- image.folder to set the folder to store uploaded image files.
- image.size to set the size in pixels of the target resized images.
Implement File Upload Service
Add a new Java package named dev.simplesolution.uploadresize.service, in the created package creates a new interface named FileUploadService as below.
FileUploadService.java
package dev.simplesolution.uploadresize.service;
import java.io.File;
import org.springframework.web.multipart.MultipartFile;
public interface FileUploadService {
File upload(MultipartFile imageFile);
}
Add a new Java package named dev.simplesolution.uploadresize.service.impl, in the created package creates a new class named FileUploadServiceImpl, in this implementation class we read the uploading image from MultipartFile object and write it to the image folder which is setting in the application.properties file.
FileUploadServiceImpl.java
package dev.simplesolution.uploadresize.service.impl;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import dev.simplesolution.uploadresize.service.FileUploadService;
@Service
public class FileUploadServiceImpl implements FileUploadService {
@Value("${image.folder}")
private String imageFolder;
private Logger logger = LoggerFactory.getLogger(FileUploadServiceImpl.class);
@Override
public File upload(MultipartFile imageFile) {
try {
Path path = Paths.get(imageFolder, imageFile.getOriginalFilename());
Files.write(path, imageFile.getBytes());
return path.toFile();
} catch (IOException e) {
logger.error(e.getMessage(), e);
return null;
}
}
}
Implement Resize Image Service
In the Java package dev.simplesolution.uploadresize.service, add a new interface named ImageService as below.
ImageService.java
package dev.simplesolution.uploadresize.service;
import java.io.File;
public interface ImageService {
boolean resizeImage(File sourceFile);
}
In the Java package dev.simplesolution.uploadresize.service.impl, add a new class named ImageServiceImpl. In this image service class we implement a method to read a given image and resize to a new image with size defined in application.properties file.
ImageServiceImpl.java
package dev.simplesolution.uploadresize.service.impl;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.imageio.ImageIO;
import org.apache.commons.io.FilenameUtils;
import org.imgscalr.Scalr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import dev.simplesolution.uploadresize.service.ImageService;
@Service
public class ImageServiceImpl implements ImageService {
@Value("${image.folder}")
private String imageFolder;
@Value("${image.size}")
private Integer imageSize;
private Logger logger = LoggerFactory.getLogger(ImageServiceImpl.class);
@Override
public boolean resizeImage(File sourceFile) {
try {
BufferedImage bufferedImage = ImageIO.read(sourceFile);
BufferedImage outputImage = Scalr.resize(bufferedImage, imageSize);
String newFileName = FilenameUtils.getBaseName(sourceFile.getName())
+ "_" + imageSize.toString() + "."
+ FilenameUtils.getExtension(sourceFile.getName());
Path path = Paths.get(imageFolder,newFileName);
File newImageFile = path.toFile();
ImageIO.write(outputImage, "jpg", newImageFile);
outputImage.flush();
return true;
} catch (IOException e) {
logger.error(e.getMessage(), e);
return false;
}
}
}
Implement Image Upload Controller
Add a new Java package named dev.simplesolution.uploadresize.controller, add a new class named ImageUploadController, in this class we use the upload service and image service from previous steps to handle upload and resize images.
ImageUploadController.java
package dev.simplesolution.uploadresize.controller;
import java.io.File;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import dev.simplesolution.uploadresize.service.FileUploadService;
import dev.simplesolution.uploadresize.service.ImageService;
@Controller
public class ImageUploadController {
@Autowired
private FileUploadService fileUploadService;
@Autowired
private ImageService imageService;
@GetMapping("")
public String uploadImage() {
return "uploadImage";
}
@PostMapping("/uploadImage")
public String uploadImage(@RequestParam("image") MultipartFile imageFile, RedirectAttributes redirectAttributes) {
if(imageFile.isEmpty()) {
redirectAttributes.addFlashAttribute("errorMessage", "Please choose file to upload.");
return "redirect:/";
}
File file = fileUploadService.upload(imageFile);
if(file == null) {
redirectAttributes.addFlashAttribute("errorMessage", "Upload failed.");
return "redirect:/";
}
boolean resizeResult = imageService.resizeImage(file);
if(!resizeResult) {
redirectAttributes.addFlashAttribute("errorMessage", "Resize failed.");
return "redirect:/";
}
redirectAttributes.addFlashAttribute("successMessage", "File upload successfully.");
return "redirect:/";
}
}
Create HTML View to Upload Image Files
Create a new HTML view file at /src/main/resources/templates/uploadImage.html to show the form allowing the user choose an image file to upload. In this HTML view we also use the Bootstrap CSS library.
uploadImage.html
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Spring Boot Web Upload and Resize Images</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Choose an image file to upload and resize.</h1>
<p class="text-danger" th:if="${errorMessage}" th:text="${errorMessage}"></p>
<p class="text-success" th:if="${successMessage}" th:text="${successMessage}"></p>
<form method="POST" enctype="multipart/form-data" action="/uploadImage">
<div class="form-group">
<label for="image">File to upload</label>
<input type="file" class="form-control-file" id="image" name="image" >
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</body>
</html>
Final Application
At this step, we have finished implementing the Spring Boot web project to upload and resize images with the source code structure as below screenshot.
Run the application and access http://localhost:8080/ you can see the application via browser as below.
Choose an image and click the Upload button you will see the upload successful message as below screenshot.
Then access the image folder which is setting in application.properties file to see there is the image file uploaded and also a new resized image file.
Download Source Code
The source code in this article can be found at: github.com/simplesolutiondev/spring-boot-upload-resize
or clone at:
git clone https://github.com/simplesolutiondev/spring-boot-upload-resize.git
or download at:
Happy Coding 😊