Spring-Image is a library built to make image upload, storage and retrieval simpler in Spring web applications. Uploads are made simpler by providing data types that can be used in Spring Documents to store MultipartFiles sent by the browser. These files can then be stored in a data store as-is or stored pre-sized to make for quicker retrieval by clients later.
A demo of the library in use can be found here.
Supported Formats | Supported Extensions |
---|---|
JPEG | .jpg, .jpeg |
PNG | .png |
BMP | .bmp, .bm |
TIFF | .tiff, .tif |
GIF | .gif |
Option 1 - Include JAR
The simplest way to leverage Spring-Image is to just download and include the .jar file. You can get the latest release from the releases page. Then just include the .jar in your Maven pom:
<dependency>
<groupId>com.github.c1phr</groupId>
<artifactId>spring-image</artifactId>
<version>0.0.6</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/spring-image.jar</systemPath>
</dependency>
Option 2 - Include Source
If you're already building a Spring web application want more control over the Spring-Image API, you can include the source right in your project.
Add the package to src/main/kotlin
and include the Kotlin stdlib in your Maven pom:
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.0.3</version>
</dependency>
You'll also need to include the following plugin to compile the Kotlin source before Java source.
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>1.0.3</version>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/java</sourceDir>
<sourceDir>src/main/kotlin</sourceDir>
<sourceDir>src/main/resources</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/test/java</sourceDir>
<sourceDir>src/test/kotlin</sourceDir>
<sourceDir>src/test/resources</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
First add an ImageDataField
type property on the object that you want to add an image to.
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY) // Optional
private ImageDataField image;
I suggest adding the @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
annotation to prevent sending the full image bytes in JSON to clients.
The simplest interface for adding images just takes in a MultipartFile object from as it's uploaded from a client. This will store the image in its original size and format.
public void setImage(MultipartFile uploadedImage) {
this.image.addItemImage(uploadedImage);
}
Images can be pre-optimized at storage time into smaller sizes that better represent your UI needs. If you are only ever going to render profile pictures in 200x200 thumbnails, Spring-Image will let you store the scaled down image so that it can be sent to clients quicker in a named size class.
public void setImage(MultipartFile uploadedImage) {
ImageSize size = new ImageSize("sm", 200, 200);
this.image.addItemImage(uploadedImage, size);
}
This will allow a smaller version of the image to be retrieved using the "sm" size class.
To store multiple different sized images, pass a List<ImageSize>
when adding images.
public void setImage(MultipartFile uploadedImage) {
ArrayList<ImageSize> sizes = new ArrayList<>();
sizes.add(new ImageSize("sm", 800, 600));
sizes.add(new ImageSize("lg", 1600, 1200));
sizes.add(new ImageSize("hd", 1920, 1080));
this.addItemImage(uploadedImage, sizes);
}
By default, Spring-Image will store the original sized image under the original
size class. This functionality can be disabled by passing false
as the last parameter.
this.addItemImage(uploadedImage, sizes, false); // Skip storing the orignal image
Spring-Image ImageDataField
allows you to retrieve ImageRecord
objects for use in your code, or helper methods for returning images directly through HTTP calls.
ImageRecord
objects can be retrieved directly from ImageDataField
by either size key or dimensions. An ImageRecord
will give access to the bytes storing the original image.
Get by size key: Returns null if the size key is not available, sizeKey defaults to "original" if not passed.
ImageRecord img = imageDataField.getImageBySize(sizeKey);
Get by dimensions: Resizes the image on demand using either the original or otherwise largest available image as the source. Note this can be slow and additional strain on the server depending on the number of on demand resize requests.
ImageRecord img = imageDataField.getImageBySize(1920, 1080);
Get by Long/Short Edge: Very similar to getting an image by dimensions, except scaling happens against just one dimension.
ImageRecord imgLongEdge = imageDataField.getImageByLongEdge(1920);
ImageRecord imgShortEdge = imageDataField.getImageByShortEdge(1080);
The HttpImageHandler
class provides an implementation of the retrieval methods described above that are all specifically tailored to writing images into HttpServletResponse
objects for use in Spring applications. None of the HTTP helpers will return data, they all write image data directly into the response. Note that the response
variable in these examples is the request's HttpServletResponse
.
The simplest method returns the "original" size key item if it's stored.
HttpImageHandler.getSize(response);
A different size key can also be passed:
HttpImageHandler.getSize("lg", response);
Getting by dimensions:
HttpImageHandler.getSize(500, 500, response);
Long and short edge:
HttpImageHandler.getSizeLongEdge(500, response);
HttpImageHandler.getSizeShortEdge(500, response);
Spring-Image the following components can be used outside of the context of an ImageDataField
.
Scaler can be found at com.springimage.utils.Scaler
, and currently supports scaling objects of type MultipartFile
, BufferedImage
, and ImageRecord
. Usage is pretty simple:
Scaler scaler = new Scaler(myImage)
myImage = scaler.ScaleImage(500, 500);
The Scaler
also exposes ScaleImageLongEdge(int)
and ScaleImageShortEdge(int)
to use instead of ScaleImage(x, y)
.
- Better test coverage
- File format conversion
- Base64 support
- SVG Support