Search in sources :

Example 1 with Rendition

use of com.day.cq.dam.api.Rendition 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);
        }
    }
}
Also used : InputStream(java.io.InputStream) Rendition(com.day.cq.dam.api.Rendition) DownloadResource(com.day.cq.commons.DownloadResource) Resource(org.apache.sling.api.resource.Resource) ImageResource(com.day.cq.commons.ImageResource) Asset(com.day.cq.dam.api.Asset) AssetHandler(com.day.cq.dam.api.handler.AssetHandler) Layer(com.day.image.Layer)

Example 2 with Rendition

use of com.day.cq.dam.api.Rendition 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);
}
Also used : Rendition(com.day.cq.dam.api.Rendition) InvocationOnMock(org.mockito.invocation.InvocationOnMock) AssetHandler(com.day.cq.dam.api.handler.AssetHandler) AssetStore(com.day.cq.dam.api.handler.store.AssetStore) BufferedImage(java.awt.image.BufferedImage) Before(org.junit.Before)

Aggregations

Rendition (com.day.cq.dam.api.Rendition)2 AssetHandler (com.day.cq.dam.api.handler.AssetHandler)2 DownloadResource (com.day.cq.commons.DownloadResource)1 ImageResource (com.day.cq.commons.ImageResource)1 Asset (com.day.cq.dam.api.Asset)1 AssetStore (com.day.cq.dam.api.handler.store.AssetStore)1 Layer (com.day.image.Layer)1 BufferedImage (java.awt.image.BufferedImage)1 InputStream (java.io.InputStream)1 Resource (org.apache.sling.api.resource.Resource)1 Before (org.junit.Before)1 InvocationOnMock (org.mockito.invocation.InvocationOnMock)1