use of com.day.cq.dam.api.handler.AssetHandler in project aem-core-wcm-components by Adobe-Marketing-Cloud.
the class AdaptiveImageServlet method resizeAndStream.
/**
* Calling this method will copy the image's bytes into the response's output stream, after performing all the needed transformations
* on the requested image.
*
* @param request the request
* @param response the response
* @param image the image component resource
* @param imageProperties the image properties
* @param resizeWidth the width to which the image has to be resized
*/
private void resizeAndStream(SlingHttpServletRequest request, SlingHttpServletResponse response, Resource image, ValueMap imageProperties, int resizeWidth) throws IOException {
if (resizeWidth < 0) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
String fileReference = imageProperties.get(DownloadResource.PN_REFERENCE, String.class);
String imageType = getImageType(request.getRequestPathInfo().getExtension());
String extension = mimeTypeService.getExtension(imageType);
Asset asset = null;
Resource imageFile = null;
if (StringUtils.isNotEmpty(fileReference)) {
// the image is coming from DAM
final Resource assetResource = request.getResourceResolver().getResource(fileReference);
if (assetResource == null) {
LOGGER.error(String.format("Unable to find resource %s used by image %s.", fileReference, image.getPath()));
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
asset = assetResource.adaptTo(Asset.class);
if (asset == null) {
LOGGER.error(String.format("Unable to adapt resource %s used by image %s to an asset.", fileReference, image.getPath()));
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
if ("gif".equalsIgnoreCase(extension)) {
LOGGER.debug("GIF asset detected; will render the original rendition.");
stream(response, asset.getOriginal().getStream(), imageType);
return;
}
} else {
imageFile = image.getChild(DownloadResource.NN_FILE);
if ("gif".equalsIgnoreCase(extension)) {
LOGGER.debug("GIF file detected; will render the original file.");
InputStream is = imageFile.adaptTo(InputStream.class);
if (is != null) {
stream(response, is, imageType);
}
return;
}
}
if (asset != null) {
int rotationAngle = getRotation(image, imageProperties);
Rectangle rectangle = getCropRect(image, imageProperties);
if (rotationAngle != 0 || rectangle != null || resizeWidth > 0) {
int originalWidth = getDimension(asset.getMetadataValue(DamConstants.TIFF_IMAGEWIDTH));
int originalHeight = getDimension(asset.getMetadataValue(DamConstants.TIFF_IMAGELENGTH));
AssetHandler assetHandler = assetStore.getAssetHandler(imageType);
Layer layer = null;
boolean appliedRotationOrCropping = false;
if (rectangle != null) {
double scaling;
Rendition webRendition = getAWebRendition(asset);
double renditionWidth = 1280D;
if (webRendition != null) {
try {
renditionWidth = Double.parseDouble(webRendition.getName().split("\\.")[2]);
LOGGER.debug("Found rendition {} with width {}px; assuming the cropping rectangle was calculated using this " + "rendition.", webRendition.getPath(), renditionWidth);
} catch (NumberFormatException e) {
LOGGER.warn("Cannot determine rendition width for {}. Will fallback to 1280px.", webRendition.getPath());
}
} else {
renditionWidth = originalWidth;
}
if (originalWidth > renditionWidth) {
scaling = (double) originalWidth / renditionWidth;
} else {
scaling = renditionWidth / originalWidth;
}
layer = new Layer(assetHandler.getImage(asset.getOriginal()));
if (Math.abs(scaling - 1.0D) != 0) {
Rectangle scaledRectangle = new Rectangle((int) (rectangle.x * scaling), (int) (rectangle.y * scaling), (int) (rectangle.getWidth() * scaling), (int) (rectangle.getHeight() * scaling));
layer.crop(scaledRectangle);
} else {
layer.crop(rectangle);
}
appliedRotationOrCropping = true;
}
if (rotationAngle != 0) {
if (layer == null) {
layer = new Layer(assetHandler.getImage(asset.getOriginal()));
}
layer.rotate(rotationAngle);
LOGGER.debug("Applied rotation transformation ({} degrees).", rotationAngle);
appliedRotationOrCropping = true;
}
if (!appliedRotationOrCropping) {
Rendition rendition = asset.getRendition(String.format(DamConstants.PREFIX_ASSET_WEB + ".%d.%d.%s", resizeWidth, resizeWidth, extension));
if (rendition != null) {
LOGGER.debug("Found rendition {} with a width equal to the resize width ({}px); rendering.", rendition.getPath(), resizeWidth);
stream(response, rendition.getStream(), imageType);
} else {
int resizeHeight = calculateResizeHeight(originalWidth, originalHeight, resizeWidth);
if (resizeHeight > 0 && resizeHeight != originalHeight) {
layer = new Layer(assetHandler.getImage(asset.getOriginal()));
layer.resize(resizeWidth, resizeHeight);
response.setContentType(imageType);
LOGGER.debug("Resizing asset {} to requested width of {}px; rendering.", asset.getPath(), resizeWidth);
layer.write(imageType, 1.0, response.getOutputStream());
} else {
LOGGER.debug("Rendering the original asset {} since its width ({}px) is either smaller than the requested " + "width ({}px) or since no resize is needed.", asset.getPath(), originalWidth, resizeWidth);
stream(response, asset.getOriginal().getStream(), imageType);
}
}
} else {
resizeAndStreamLayer(response, layer, imageType, resizeWidth);
}
} else {
LOGGER.debug("No need to perform any processing on asset {}; rendering.", asset.getPath());
stream(response, asset.getOriginal().getStream(), imageType);
}
} else if (imageFile != null) {
InputStream is = null;
try {
is = imageFile.adaptTo(InputStream.class);
int rotationAngle = getRotation(image, imageProperties);
Rectangle rectangle = getCropRect(image, imageProperties);
if (rotationAngle != 0 || rectangle != null || resizeWidth > 0) {
Layer layer = null;
if (rectangle != null) {
layer = new Layer(is);
layer.crop(rectangle);
LOGGER.debug("Applied cropping transformation.");
}
if (rotationAngle != 0) {
if (layer == null) {
layer = new Layer(is);
}
layer.rotate(rotationAngle);
LOGGER.debug("Applied rotation transformation ({} degrees).", rotationAngle);
}
if (layer == null) {
layer = new Layer(is);
}
resizeAndStreamLayer(response, layer, imageType, resizeWidth);
} else {
LOGGER.debug("No need to perform any processing on file {}; rendering.", imageFile.getPath());
stream(response, is, imageType);
}
} finally {
IOUtils.closeQuietly(is);
}
}
}
use of com.day.cq.dam.api.handler.AssetHandler in project aem-core-wcm-components by Adobe-Marketing-Cloud.
the class AdaptiveImageServletTest method init.
@Before
public void init() throws IOException {
resourceResolver = aemContext.resourceResolver();
servlet = new AdaptiveImageServlet();
Whitebox.setInternalState(servlet, "mimeTypeService", mockedMimeTypeService);
AssetHandler assetHandler = mock(AssetHandler.class);
AssetStore assetStore = mock(AssetStore.class);
when(assetStore.getAssetHandler(anyString())).thenReturn(assetHandler);
when(assetHandler.getImage(any(Rendition.class))).thenAnswer(new Answer<BufferedImage>() {
@Override
public BufferedImage answer(InvocationOnMock invocationOnMock) throws Throwable {
Rendition rendition = invocationOnMock.getArgumentAt(0, Rendition.class);
return ImageIO.read(rendition.getStream());
}
});
Whitebox.setInternalState(servlet, "assetStore", assetStore);
activateServlet(servlet);
}
use of com.day.cq.dam.api.handler.AssetHandler in project aem-core-wcm-components by Adobe-Marketing-Cloud.
the class AdaptiveImageServletTest method setUp.
@BeforeEach
void setUp() throws Exception {
internalSetUp(TEST_BASE);
context.load().binaryFile("/image/" + PNG_IMAGE_RECTANGLE_BINARY_NAME, PNG_RECTANGLE_ASSET_PATH + "/jcr:content/renditions/original");
context.load().binaryFile("/image/" + "cq5dam.web.1280.1280_" + PNG_IMAGE_BINARY_NAME, PNG_RECTANGLE_ASSET_PATH + "/jcr:content/renditions/cq5dam.web.1280.1280.png");
context.load().binaryFile("/image/" + PNG_IMAGE_SMALL_BINARY_NAME, PNG_SMALL_ASSET_PATH + "/jcr:content/renditions/original");
context.load().binaryFile("/image/" + "cq5dam.web.1280.1280_" + PNG_IMAGE_BINARY_NAME, PNG_SMALL_ASSET_PATH + "/jcr:content/renditions/cq5dam.web.1280.1280.png");
resourceResolver = context.resourceResolver();
AssetHandler assetHandler = mock(AssetHandler.class);
AssetStore assetStore = mock(AssetStore.class);
AdaptiveImageServletMetrics metrics = mock(AdaptiveImageServletMetrics.class);
when(metrics.startDurationRecording()).thenReturn(mock(Timer.Context.class));
when(assetStore.getAssetHandler(anyString())).thenReturn(assetHandler);
IIORegistry registry = IIORegistry.getDefaultInstance();
Iterator iter = registry.getServiceProviders(ImageReaderSpi.class, true);
// Force ImageIO to pick TwelveMonkeys plugins for JPG and TIFF
while (iter.hasNext()) {
ImageReaderSpi provider = (ImageReaderSpi) iter.next();
if (!provider.getClass().getName().contains("twelvemonkeys") && ((Arrays.stream(provider.getFormatNames()).filter(f -> "JPG".equalsIgnoreCase(f)).count() > 0) || (Arrays.stream(provider.getFormatNames()).filter(f -> "TIFF".equalsIgnoreCase(f)).count() > 0))) {
registry.deregisterServiceProvider(provider);
}
}
when(assetHandler.getImage(any(Rendition.class))).thenAnswer(invocation -> {
Rendition rendition = invocation.getArgument(0);
return ImageIO.read(rendition.getStream());
});
servlet = new AdaptiveImageServlet(mockedMimeTypeService, assetStore, metrics, ADAPTIVE_IMAGE_SERVLET_DEFAULT_RESIZE_WIDTH, AdaptiveImageServlet.DEFAULT_MAX_SIZE);
testLogger = Utils.mockLogger(AdaptiveImageServlet.class, "LOGGER");
}
Aggregations