Surely you will have had to define a custom entity in the Service Builder to which to associate an image, such as an icon or a cover image.

Typically in these cases, you start to work with the Document Library by creating folders, sub-folders, permissions, trying to manage the entire flow of creating and updating the image itself.

But once again, Liferay's API help us and simplify our lives!

The first thing to do is to define the custom entity within the service.xml file, with all the image fields as long type; this because we are going to save only the primary key of the image.

I said all the image fields because the system is not limited to a single image; just define a long field in the custom entity for each image you want to associate with the entity itself.

Let's suppose that we have defined a Book entity and we want to associate an image for the cover: we will define the service.xml field as follows:

<column name="coverImageId" type="long" /> 

Most of the work has been done; to manage the image (typically in the *LocalServiceImpl class) you just need to invoke a single, simple method:

    BaseModel<?> baseModel,
    boolean hasImage,
    byte[] bytes,
    String fieldName,
    long maxSize,
    int maxHeight,
    int maxWidth)
throws PortalException;

All the dirty work will be done by this method, based on the parameters values:

  • baseModel, is the instance of the class to which to associate the image (an object of class Book);
  • hasImage, if false the current image will be deleted from portal and the entity field will be set to 0; otherwise the image will be uploaded to the portal and the entity field will be set to the primary key of the image;
  • bytes, is the image to upload to the portal (can be null);
  • fieldName, is the name of the field where we will save the primary key of the image (e.g. coverImageId);
  • maxSize, max size (in bytes) for the image;
  • maxHeight, max height (in pixel) for the image; if the value is greater than 0 the image will be resized on upload;
  • maxWidth, max width (in pixel) for the image; if the value is greater than 0 the image will be resized on upload.
Book book = ...

// Image add/update
PortalUtil.updateImageId(book, true, bytes, "coverImageId", 0, 0, 0);

// Image delete PortalUtil.updateImageId(book, false, null, "coverImageId", 0, 0, 0);
// Image add/update with resize PortalUtil.updateImageId(book, true, bytes, "coverImageId", 0, 640, 480);

Ok, but where the image is saved exactly?

If you really want to know it, have a look to ImageLocalServiceImpl.updateImage method but the image is saved in the Document Library inside an hidden section not visible to the users; the image data are instead registered in the Image table.

That's cool! But how can I view the image?

Just create a string like the following:

long imageId = book.getCoverImageId();
String url = "/image/logo?image_id=" + imageId + "&t=" + WebServerServletTokenUtil.getToken(imageId);

All the magic is made by the /image path mapped in a portal servlet; instead the second piece /logo can actually be customized as you wish.