Skip to content

Commit

Permalink
introduce OSGI config parameter to switch between relative and absolu…
Browse files Browse the repository at this point in the history
…te cropping, use relative cropping by default
  • Loading branch information
stefanseifert committed Aug 22, 2024
1 parent 588a3ce commit 7fc5e2b
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ private ParameterMap() {
}

@NotNull
static Map<String, Object> build(@NotNull Asset asset, @NotNull WebOptimizedImageDeliveryParams params) {
static Map<String, Object> build(@NotNull Asset asset, @NotNull WebOptimizedImageDeliveryParams params,
@NotNull WebOptimizedImageDeliveryCropOption cropOption) {
String path = asset.getPath();
String seoName = FilenameUtils.getBaseName(asset.getName());
String format = StringUtils.toRootLowerCase(FilenameUtils.getExtension(asset.getName()));
Expand All @@ -85,7 +86,7 @@ static Map<String, Object> build(@NotNull Asset asset, @NotNull WebOptimizedImag
map.put(PARAM_WIDTH, width.toString());
}
if (cropDimension != null) {
map.put(PARAM_CROP, createCroppingString(asset, cropDimension));
map.put(PARAM_CROP, createCroppingString(asset, cropDimension, cropOption));
}
if (rotation != null && rotation != 0) {
map.put(PARAM_ROTATE, rotation.toString());
Expand All @@ -96,13 +97,15 @@ static Map<String, Object> build(@NotNull Asset asset, @NotNull WebOptimizedImag
return map;
}

private static @NotNull String createCroppingString(
@NotNull Asset asset,
@NotNull CropDimension cropDimension) {
Dimension imageDimension = loadImageDimension(asset);
return imageDimension == null || imageDimension.getWidth() <= 0 || imageDimension.getHeight() <= 0
? cropDimension.getCropStringWidthHeight()
: createRelativeCroppingString(imageDimension, cropDimension);
private static @NotNull String createCroppingString(@NotNull Asset asset, @NotNull CropDimension cropDimension,
@NotNull WebOptimizedImageDeliveryCropOption cropOption) {
if (cropOption == WebOptimizedImageDeliveryCropOption.RELATIVE_PARAMETERS) {
Dimension imageDimension = loadImageDimension(asset);
if (imageDimension != null && imageDimension.getWidth() > 0 && imageDimension.getHeight() > 0) {
return createRelativeCroppingString(imageDimension, cropDimension);
}
}
return cropDimension.getCropStringWidthHeight();
}

private static @Nullable Dimension loadImageDimension(@NotNull Asset asset) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2024 wcm.io
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package io.wcm.handler.mediasource.dam.impl.weboptimized;

/**
* Choose how to calculate/apply cropping parameter when using Web-Optimized image delivery.
*/
public enum WebOptimizedImageDeliveryCropOption {

/**
* Crop renditions using relative percentage values as parameters (e.g. crop=0.0p,5.0p,100.0p,80.0p),
* based on the original image dimensions.
*/
RELATIVE_PARAMETERS,

/**
* Crop renditions using absolute pixel values as parameters (e.g. crop=0,10,200,100),
* based on the original image dimensions.
*/
ABSOLUTE_PARAMETERS

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ public interface WebOptimizedImageDeliveryService {
*/
boolean isEnabled();

/**
* Cropping option to use.
* @return Cropping option
*/
WebOptimizedImageDeliveryCropOption getCropOption();

/**
* Get delivery URL for a rendition of an asset.
* @param asset Asset
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,43 @@ public class WebOptimizedImageDeliveryServiceImpl implements WebOptimizedImageDe
description = "Enable support for Web-Optimized Image Delivery (if available).")
boolean enabled() default true;

@AttributeDefinition(
name = "Cropping Option",
description = "Use relative cropping parameters (e.g. crop=0.0p,5.0p,100.0p,80.0p) "
+ "or absolute cropping paremters (e.g. crop=0,10,200,100), both based on the original image dimensions.")
WebOptimizedImageDeliveryCropOption cropOption() default WebOptimizedImageDeliveryCropOption.RELATIVE_PARAMETERS;

}

@Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
private AssetDelivery assetDelivery;

private boolean enabled;
private WebOptimizedImageDeliveryCropOption cropOption;

@Activate
private void activate(Config config) {
this.enabled = config.enabled();
this.cropOption = config.cropOption();
}

@Override
public boolean isEnabled() {
return enabled && this.assetDelivery != null;
}

@Override
public WebOptimizedImageDeliveryCropOption getCropOption() {
return cropOption;
}

@Override
public @Nullable String getDeliveryUrl(@NotNull Asset asset, @NotNull WebOptimizedImageDeliveryParams params) {
if (!isEnabled()) {
return null;
}
Resource resource = AdaptTo.notNull(asset, Resource.class);
Map<String, Object> parameterMap = ParameterMap.build(asset, params);
Map<String, Object> parameterMap = ParameterMap.build(asset, params, cropOption);
return assetDelivery.getDeliveryURL(resource, parameterMap);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

Expand All @@ -37,9 +40,6 @@
import io.wcm.testing.mock.aem.junit5.AemContextExtension;
import io.wcm.wcm.commons.contenttype.ContentType;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@ExtendWith(AemContextExtension.class)
class WebOptimizedImageDeliveryServiceImplTest {

Expand Down Expand Up @@ -97,11 +97,30 @@ void testGetDeliveryUrl_relativeCropping() {
Asset asset = context.create().asset("/content/dam/Test_1.jpg", 1920, 604, ContentType.JPEG);
String assetId = MockAssetDelivery.getAssetId(asset);

assertEquals(WebOptimizedImageDeliveryCropOption.RELATIVE_PARAMETERS, underTest.getCropOption());

String cropping = URLEncoder.encode(createRelativeCroppingString(0.54, 0, 0.42, 1), StandardCharsets.UTF_8);
assertEquals("/adobe/dynamicmedia/deliver/" + assetId + "/test-1.jpg?c=" + cropping + "&preferwebp=true&width=806",
underTest.getDeliveryUrl(asset, new WebOptimizedImageDeliveryParams()
.width(806L)
.cropDimension(new CropDimension(1028, 0, 806, 604))));
}

@Test
void testGetDeliveryUrl_absoluteCropping() {
context.registerInjectActivateService(MockAssetDelivery.class);
WebOptimizedImageDeliveryService underTest = context.registerInjectActivateService(WebOptimizedImageDeliveryServiceImpl.class,
"cropOption", WebOptimizedImageDeliveryCropOption.ABSOLUTE_PARAMETERS.name());
Asset asset = context.create().asset("/content/dam/Test_1.jpg", 1920, 604, ContentType.JPEG);
String assetId = MockAssetDelivery.getAssetId(asset);

assertEquals(WebOptimizedImageDeliveryCropOption.ABSOLUTE_PARAMETERS, underTest.getCropOption());

String cropping = URLEncoder.encode("1028,0,806,604", StandardCharsets.UTF_8);
assertEquals("/adobe/dynamicmedia/deliver/" + assetId + "/test-1.jpg?c=" + cropping + "&preferwebp=true&width=806",
underTest.getDeliveryUrl(asset, new WebOptimizedImageDeliveryParams()
.width(806L)
.cropDimension(new CropDimension(1028, 0, 806, 604))));
}

}

0 comments on commit 7fc5e2b

Please sign in to comment.