Skip to content

Commit

Permalink
move relative crop creation to separate class, use 1 fraction for per…
Browse files Browse the repository at this point in the history
…centage values
  • Loading branch information
stefanseifert committed Aug 22, 2024
1 parent 7fc5e2b commit 87a5ddf
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static Map<String, Object> build(@NotNull Asset asset, @NotNull WebOptimizedImag
if (cropOption == WebOptimizedImageDeliveryCropOption.RELATIVE_PARAMETERS) {
Dimension imageDimension = loadImageDimension(asset);
if (imageDimension != null && imageDimension.getWidth() > 0 && imageDimension.getHeight() > 0) {
return createRelativeCroppingString(imageDimension, cropDimension);
return RelativeCroppingString.createFromCropDimension(cropDimension, imageDimension);
}
}
return cropDimension.getCropStringWidthHeight();
Expand All @@ -115,28 +115,4 @@ static Map<String, Object> build(@NotNull Asset asset, @NotNull WebOptimizedImag
: AssetRendition.getDimension(originalRendition);
}

private static @NotNull String createRelativeCroppingString(
@NotNull Dimension imageDimension,
@NotNull CropDimension cropDimension) {
double x1 = cropDimension.getLeft();
double y1 = cropDimension.getTop();
double x2 = cropDimension.getRight();
double y2 = cropDimension.getBottom();
double left = x1 / imageDimension.getWidth();
double top = y1 / imageDimension.getHeight();
double width = (x2 - x1) / imageDimension.getWidth();
double height = (y2 - y1) / imageDimension.getHeight();
return createRelativeCroppingString(left, top, width, height);
}

static @NotNull String createRelativeCroppingString(double left, double top, double width, double height) {
return String.format("%.0fp,%.0fp,%.0fp,%.0fp",
toPercentage(left), toPercentage(top),
toPercentage(width), toPercentage(height));
}

private static double toPercentage(double fraction) {
return Math.round(fraction * 100);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* #%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;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;

import org.jetbrains.annotations.NotNull;

import io.wcm.handler.media.CropDimension;
import io.wcm.handler.media.Dimension;

/**
* Creates relative crop string with percentage values as required by the Web-Optimized Image Delivery API.
* It uses one fractional digit for the percentage values.
*/
final class RelativeCroppingString {

private static final NumberFormat DECIMAL_FORMAT = new DecimalFormat("0.0", new DecimalFormatSymbols(Locale.US));

private RelativeCroppingString() {
// static methods only
}

static @NotNull String createFromCropDimension(
@NotNull CropDimension cropDimension, @NotNull Dimension imageDimension) {
double x1 = cropDimension.getLeft();
double y1 = cropDimension.getTop();
double left = x1 / imageDimension.getWidth();
double top = y1 / imageDimension.getHeight();
double width = (double)cropDimension.getWidth() / imageDimension.getWidth();
double height = (double)cropDimension.getHeight() / imageDimension.getHeight();
return create(left, top, width, height);
}

static @NotNull String create(double left, double top, double width, double height) {
return String.format("%sp,%sp,%sp,%sp",
toPercentage(left), toPercentage(top),
toPercentage(width), toPercentage(height));
}

private static String toPercentage(double fraction) {
return DECIMAL_FORMAT.format(Math.round(fraction * 1000d) / 10d);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void testAsset_JPEG_Rescale() {
void testAsset_JPEG_AutoCrop() {
Asset asset = createSampleAsset("/filetype/sample.jpg", ContentType.JPEG);
buildAssertMedia_AutoCrop(asset, 50, 50,
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.jpg?c=25p%2C0p%2C50p%2C100p&preferwebp=true&quality=85&width=50",
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.jpg?c=25.0p%2C0.0p%2C50.0p%2C100.0p&preferwebp=true&quality=85&width=50",
ContentType.JPEG);
}

Expand All @@ -87,7 +87,7 @@ void testAsset_JPEG_AutoCrop() {
void testAsset_JPEG_AutoCrop_ImageQuality() {
Asset asset = createSampleAsset("/filetype/sample.jpg", ContentType.JPEG);
buildAssertMedia_AutoCrop(asset, 50, 50,
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.jpg?c=25p%2C0p%2C50p%2C100p&preferwebp=true&quality=60&width=50",
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.jpg?c=25.0p%2C0.0p%2C50.0p%2C100.0p&preferwebp=true&quality=60&width=50",
ContentType.JPEG, 0.6d);
}

Expand All @@ -97,7 +97,7 @@ void testAsset_JPEG_CropWithExplicitRendition() {
Asset asset = createSampleAsset("/filetype/sample.jpg", ContentType.JPEG);
context.create().assetRendition(asset, "square.jpg", 50, 50, ContentType.JPEG);
buildAssertMedia_AutoCrop(asset, 50, 50,
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.jpg?c=25p%2C0p%2C50p%2C100p&preferwebp=true&quality=85&width=50",
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.jpg?c=25.0p%2C0.0p%2C50.0p%2C100.0p&preferwebp=true&quality=85&width=50",
ContentType.JPEG);
}

Expand All @@ -124,7 +124,7 @@ void testAsset_GIF_Rescale() {
void testAsset_GIF_AutoCrop() {
Asset asset = createSampleAsset("/filetype/sample.gif", ContentType.GIF);
buildAssertMedia_AutoCrop(asset, 50, 50,
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.gif?c=25p%2C0p%2C50p%2C100p&preferwebp=true&quality=85&width=50",
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.gif?c=25.0p%2C0.0p%2C50.0p%2C100.0p&preferwebp=true&quality=85&width=50",
ContentType.GIF);
}

Expand All @@ -151,7 +151,7 @@ void testAsset_PNG_Rescale() {
void testAsset_PNG_AutoCrop() {
Asset asset = createSampleAsset("/filetype/sample.png", ContentType.PNG);
buildAssertMedia_AutoCrop(asset, 50, 50,
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.png?c=25p%2C0p%2C50p%2C100p&preferwebp=true&quality=85&width=50",
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.png?c=25.0p%2C0.0p%2C50.0p%2C100.0p&preferwebp=true&quality=85&width=50",
ContentType.PNG);
}

Expand All @@ -178,7 +178,7 @@ void testAsset_TIFF_Rescale() {
void testAsset_TIFF_AutoCrop() {
Asset asset = createSampleAsset("/filetype/sample.tif", ContentType.TIFF);
buildAssertMedia_AutoCrop(asset, 50, 50,
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.jpg?c=25p%2C0p%2C50p%2C100p&preferwebp=true&quality=85&width=50",
"/adobe/dynamicmedia/deliver/" + getAssetId(asset) + "/sample.jpg?c=25.0p%2C0.0p%2C50.0p%2C100.0p&preferwebp=true&quality=85&width=50",
ContentType.JPEG);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ void test4_3_WebOptimizedImageDelivery() {
.build();

assertUriTemplate(media.getRendition(), SCALE_WIDTH, 160, 120,
"/adobe/dynamicmedia/deliver/" + assetId + "/sample.jpg?c=8p%2C0p%2C83p%2C100p&preferwebp=true&quality=85&width={width}");
"/adobe/dynamicmedia/deliver/" + assetId + "/sample.jpg?c=8.3p%2C0.0p%2C83.3p%2C100.0p&preferwebp=true&quality=85&width={width}");
assertUriTemplate(media.getRendition(), SCALE_HEIGHT, 160, 120,
"/content/dam/folder1/sample.jpg/_jcr_content/renditions/original.image_file.0.{height}.16,0,176,120.file/sample.jpg");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* #%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;

import static io.wcm.handler.mediasource.dam.impl.weboptimized.RelativeCroppingString.create;
import static io.wcm.handler.mediasource.dam.impl.weboptimized.RelativeCroppingString.createFromCropDimension;
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

import io.wcm.handler.media.CropDimension;
import io.wcm.handler.media.Dimension;


class RelativeCroppingStringTest {

@Test
void testCreate() {
assertEquals("0.0p,0.0p,100.0p,100.0p", create(0.0, 0.0, 1.0, 1.0));
assertEquals("15.0p,20.0p,55.0p,60.0p", create(0.15, 0.20, 0.55, 0.60));
assertEquals("15.1p,21.3p,49.5p,59.2p", create(0.1512, 0.2131, 0.4954, 0.5915));
}

@Test
void testCreateFromCropDimension() {
assertEquals("0.0p,0.0p,100.0p,100.0p", createFromCropDimension(new CropDimension(0, 0, 200, 100), new Dimension(200, 100)));
assertEquals("6.5p,55.0p,52.5p,67.0p", createFromCropDimension(new CropDimension(13, 55, 105, 67), new Dimension(200, 100)));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
*/
package io.wcm.handler.mediasource.dam.impl.weboptimized;

import static io.wcm.handler.mediasource.dam.impl.weboptimized.ParameterMap.createRelativeCroppingString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
Expand Down Expand Up @@ -84,7 +83,7 @@ void testGetDeliveryUrl_AssetDeliveryPresent() {
assertEquals("/adobe/dynamicmedia/deliver/" + assetId + "/test-1.jpg?preferwebp=true",
underTest.getDeliveryUrl(asset, new WebOptimizedImageDeliveryParams()));

String cropping = URLEncoder.encode(createRelativeCroppingString(0, 0, 0.2, 0.4), StandardCharsets.UTF_8);
String cropping = URLEncoder.encode(RelativeCroppingString.create(0, 0, 0.2, 0.4), StandardCharsets.UTF_8);
assertEquals("/adobe/dynamicmedia/deliver/" + assetId + "/test-1.jpg?c=" + cropping + "&preferwebp=true&r=90&width=10",
underTest.getDeliveryUrl(asset, new WebOptimizedImageDeliveryParams()
.width(10L).cropDimension(new CropDimension(0, 0, 2, 4)).rotation(90)));
Expand All @@ -99,11 +98,11 @@ void testGetDeliveryUrl_relativeCropping() {

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

String cropping = URLEncoder.encode(createRelativeCroppingString(0.54, 0, 0.42, 1), StandardCharsets.UTF_8);
String cropping = URLEncoder.encode(RelativeCroppingString.create(0.535, 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))));
underTest.getDeliveryUrl(asset, new WebOptimizedImageDeliveryParams()
.width(806L)
.cropDimension(new CropDimension(1028, 0, 806, 604))));
}

@Test
Expand Down

0 comments on commit 87a5ddf

Please sign in to comment.