![]() |
This article is brought to you by Tetiana Antonenko, EPAM Java developer |
Here I’m going to share some things we made possible together with Rauf for the “EPAM Hybris Competency Center Contest – Fall 2016”. We were tasked with building, from scratch, an extension for the SAP Hybris Commerce platform.

We decided to choose the topic Rauf explained in this blog before, “Crop and resize in Product Cockpit”, and extend it with new features. Even though the idea and title were not new, our vision for the implementation and user interface was completely different and seemed very challenging. Eventually, we won the contest!
[Scroll to the end of the article to see a demonstration]
Crop and resize module: The what, why, and how
The target is to resize and crop images to a given size directly in hybris Product Cockpit. With this extension, you no longer need to resize and crop each image by hand using tools such as Photoshop or Gimp; image renditions will be generated on the fly based on transformation rules managed by the administrators.
The way things are in hybris
There are different image types in the product data in Hybris, to name a few:
- Thumbnail type, for search results and category pages
- Normal/picture type, for the product page, as the main picture
- Detailed type, for pop-up gallery pages and other needs

Hybris expects that all uploaded images have:
- The right format (JPG/GIF/PNG)
- The right proportions/image size
- Autocorrected
- Already web-optimized
Hybris provides no validation for image data; there is no interactive image processing tool.
Why is it not good?
Thumbnails
Thumbnails are not simply downscaled versions of the full-size image. Displaying a significant part of the picture instead of the full frame can allow the use of a smaller thumbnail while maintaining recognizability.
For example, when thumbnailing a full-body portrait of a person, it may be better to show the face slightly reduced than an indistinct figure.

Product Page Images
Product page images are commonly similar in terms of proportions, which might not be true for the detailed images of the same products.
Sometimes we need to have different product page templates for different types of products to present the products better:

Breakpoints
If you want to use different images for different devices/resolutions and make your website responsive, you need to standardize the resolutions.

Browser scaling: easy-to-miss errors
Different images need different rendering/scaling algorithms. Below you can see that crisp edges work better for some images (checkers as an example), while real-life images require another scaling algorithm to look better at a different size.

Manual solution? Yes!
Cropping and resizing an image is easy in any image editor. Where it becomes tedious, though, is when you have to repeat this process for dozens or hundreds of images. Think: open the image in Photoshop, crop it, create a thumbnail, save it, and repeat for each of your images.
And if the result is not good, you have to do it all over again. One could define a macro to do it quickly, but unfortunately every image has to be cropped in a different area, which is why this process can only be done by hand.
We propose a totally different approach, allowing you to set a cropping area in seconds and redefine it if you don’t like it.

hybris OOTB automation?
In the default hybris package, the automatic image resize functionality is provided by Mediaconversion.
The module has some severe limitations that make it hardly suitable for most projects. To name a few:
- MAJOR: MediaConversion module is not integrated into Product Cockpit.
- MAJOR: No cropping feature in MediaConversion.
- MAJOR: OOTB MediaConversion module is not interactive.
- Minor: OOTB MediaConversion module uses the third-party tool ImageMagick.
Our solution
Interactive cropping tool. The cropping area is configurable for each cropping group.

Configurable. You can specify one or more source fields and one or more target fields, as well as the conversion rules and parameters. Data-driven: all configuration is in the database.

One target field can have more than one source field.
- This pattern can be used for applying different types of renditions to the same target field. For example, different watermarks* for the same field.
One source field can have more than one conversion rule (and target field).
- This pattern can be used if you have one master image and a number of renditions (thumbnail, product page image, detailed image) of different proportions.
Product Cockpit integration
The solution has already been integrated into Product Cockpit and can be easily integrated into CMS Cockpit or SmartEdit.
Wizard
The solution is implemented as a wizard that helps administrators populate the image-related fields with “one click”.

The system supports one or more source images. For example, an administrator can upload one image for a thumbnail and another image for the product page. After that, the administrator will be asked to crop the images. The cropped and resized versions of these images will be saved into designated product attributes (configurable for each source image).
Ready to grow
At the moment, the module is configured for crop & resize only. However, the data model and some components are ready for the next steps: watermarking, rotating, and flipping images.

Data model
In the diagram below you can see a simplified data model for the extension.

- CR_Configuration defines a configuration for each source image configuration. The configuration consists of conversion rules.
- Conversion Rule defines conversion parameters for each target field. Conversion Rule refers to the TargetImageFilterConfiguration.
- TargetImageFilterConfiguration defines image-specific parameters, such as dimensions, formats, cropping shapes, etc.
User Interface
The launcher is integrated into the Product Cockpit Editor area.

The configuration says that imageOriginals1 and imageOriginals2 contain source images. You can create renditions separately for each source field or for all fields in one go.
“Create image variants” launches a cropping images window. Once the cropping is done, the downscaled and cropped versions of the images are saved into the target product attributes.
Challenges and technical details
GetMediaModelFromCurrentProduct
protected Optional<MediaModel> getMediaModelFromCurrentProduct(String sourceFieldName) {
ObjectValueContainer.ObjectValueHolder value = UISessionUtils.getCurrentSession().getCurrentPerspective().getEditorArea().getEditorAreaController()
.getModel().getCurrentObjectValues()
.getValue(UISessionUtils.getCurrentSession().getTypeService().getPropertyDescriptor("Product." + sourceFieldName), null);
if (value.getCurrentValue() instanceof TypedObject) {
return Optional.ofNullable((MediaModel) ((TypedObject) value.getCurrentValue()).getObject());
}
List currentValues = (List) value.getCurrentValue();
return currentValues.stream().findAny();
}Uploading an image by product attribute name
For uploading, we used Fileupload.class.
For saving the results, we used:
modelService.setAttributeValue(productModel, targetAttributeName, imageMediaModel);Image Crop interface
Integrating third-party JavaScript libraries into hybris cockpit was one of the challenges in the project. We used jquery.js and croppie.js for the pop-up window. These libraries are completely incompatible with the old version (3.6.4) of ZK Framework. In addition to that, hybris doesn’t allow adding/replacing JavaScript libraries without touching the platform code.
Certainly, the solution is IFRAMEs.
Window window = (Window) Executions.createComponents("/cropandresize/interactiveCropWindow.zul", null, params);
...
interactiveCropWindow.zul
<?xml version="1.0" encoding="UTF-8"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver" ?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<zk xmlns:h="http://www.w3.org/1999/xhtml" xmlns:zk="http://www.zkoss.org/2005/zk">
<window title="Image Crop" border="normal" id="win">
<button onClick="wizardBean.doResizeAndSave(createCroppedImageEventListener);win.detach();" label="Close Window" visible="false" />
<iframe id="iframe" width="100%" height="100%" src="/../cropandresize/doCrop?${arg.pathUrl}">
</iframe>
</window>
</zk>If pushing data from ZK to Product Cockpit is a more or less trivial thing, the reverse operation is much more challenging. We send an event to a ZK-powered button in the parent window to close the popup and perform the additional steps when the closing event is received.
