Accessibility Now
Join our upcoming webinar about accessibility standards and legislation. May 19, 2022.
Blog

Saving and displaying images using JPA

By  
Diego Sanz Villafruela
·
On Oct 31, 2018 10:00:00 AM
·

Saving and displaying images is an essential part of many Web applications. A typical use case is to store profile pictures.

There are 2 common methods to store images:

  1. Storing the image in a folder and saving the path in the database.
  2. Storing the image (bytes) in the database.

The first method is quite straightforward to implement but causes some extra hassle with authorization, and also deployment. The method described in this tutorial is the second one, which focuses on saving and retrieving images from the database.

Now with distributed native file systems and Content Delivery Networks, the first method is more efficient. However, there are some projects where images need to be saved in a DB, especially in the health sector when the images contain sensitive information.

Storing Image Bytes

The first step is to create the JPA entity where the image will be stored.

In the case of a profile picture, the user entity would be:

@Entity(name = "UserInfo") // "User" is a reserved word in some SQL implementations
public class User extends IdentifiedStorageObject {

    private String name;
    private String surname;
    private String email;

    @Lob
    @Basic(fetch = FetchType.LAZY)
    private byte[] profilePicture;

    ...   
}
	

Note: @javax.persistence.Lob signifies that the annotated field should be represented as BLOB (binary data).

Creating an Image from Bytes

To create an image from bytes, it is necessary to encapsulate the bytes inside a ByteArrayInputStream and create a StreamResource that will be given to the constructor of the image.

public Image generateImage(User user) {
    Long id = user.getId();
    StreamResource sr = new StreamResource("user", () ->  {
        User attached = userRepository.findWithPropertyPictureAttachedById(id);
        return new ByteArrayInputStream(attached.getProfilePicture());
    });
    sr.setContentType("image/png");
    Image image = new Image(sr, "profile-picture");
    return image;
}
	

Displaying an Image

Once the image is created, attributes such as height and width can be modified. After that, it can be added to a container/layout (Div, Horizontal/Vertical layout) to be displayed.

Image image = generateImage(user);

if (image != null) {
    image.setWidth("75px");
    image.setHeight("75px");
}
	

Uploading an Image

The initUploaderImage creates an uploader that saves the image in the database and shows the uploaded image inside a container(Div).

private void initUploaderImage() {
    MultiFileMemoryBuffer buffer = new MultiFileMemoryBuffer();
    upload = new Upload(buffer);
    upload.setAcceptedFileTypes("image/jpeg","image/jpg", "image/png", "image/gif");

    upload.addSucceededListener(event -> {
        String attachmentName = event.getFileName();
        try {
            // The image can be jpg png or gif, but we store it always as png file in this example
            BufferedImage inputImage = ImageIO.read(buffer.getInputStream(attachmentName));
            ByteArrayOutputStream pngContent = new ByteArrayOutputStream();
            ImageIO.write(inputImage, "png", pngContent);
            saveProfilePicture(pngContent.toByteArray());
            showImage();
        } catch (IOException e) {
            e.printStackTrace();
        }
    });
    add(upload);
}

private void saveProfilePicture(byte[] imageBytes) {
    user.setProfilePicture(imageBytes);
    user = userRepository.save(user);
}

private void showImage() {
    Image image = imageService.generateImage(user);
    image.setHeight("100%");
    imageContainer.removeAll();
    imageContainer.add(image);
}
	

Result

If everything goes well, a new profile picture should be set when the user uploads a new image. The result should be something similar to this:

Code

An example can be found in the following GitHub repository:

https://github.com/DiegoSanzVi/saving_displaying_images_db

Diego Sanz Villafruela
You haven't yet written a blog author profile for yourself. Go to My Account page to write a short description of yourself.
Other posts by Diego Sanz Villafruela