Search in sources :

Example 1 with Layer

use of com.day.image.Layer 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 Layer

use of com.day.image.Layer in project acs-aem-commons by Adobe-Consulting-Services.

the class LetterPillarBoxImageTransformerImplTest method testTransform_invalidHeight.

@Test
public void testTransform_invalidHeight() throws Exception {
    final int width = 400;
    final int height = -100;
    final int targetheight = 225;
    map.put("width", width);
    map.put("height", height);
    ValueMap properties = new ValueMapDecorator(map);
    final Layer mockLayer = mock(Layer.class);
    final Transformer transformer = new Transformer(mockLayer);
    when(layer.getWidth()).thenReturn(START_WIDTH, START_WIDTH, width);
    when(layer.getHeight()).thenReturn(START_HEIGHT, START_HEIGHT, targetheight);
    doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt());
    transformer.transform(layer, properties);
    assertTrue("Layer constructor was not intercepted.", transformer.layerCreated);
    verify(layer, times(3)).getWidth();
    verify(layer, times(3)).getHeight();
    verify(layer, times(1)).resize(width, targetheight);
    verify(mockLayer, times(1)).blit(layer, 0, 0, width, targetheight, 0, 0);
    verifyNoMoreInteractions(layer);
    verifyNoMoreInteractions(mockLayer);
}
Also used : ValueMap(org.apache.sling.api.resource.ValueMap) ValueMapDecorator(org.apache.sling.api.wrappers.ValueMapDecorator) Layer(com.day.image.Layer) Test(org.junit.Test)

Example 3 with Layer

use of com.day.image.Layer in project acs-aem-commons by Adobe-Consulting-Services.

the class LetterPillarBoxImageTransformerImplTest method testTransform_invalidWifth.

@Test
public void testTransform_invalidWifth() throws Exception {
    final int width = -100;
    final int height = 225;
    final int targetWidth = 400;
    map.put("width", width);
    map.put("height", height);
    ValueMap properties = new ValueMapDecorator(map);
    final Layer mockLayer = mock(Layer.class);
    final Transformer transformer = new Transformer(mockLayer);
    when(layer.getWidth()).thenReturn(START_WIDTH, START_WIDTH, targetWidth);
    when(layer.getHeight()).thenReturn(START_HEIGHT, START_HEIGHT, height);
    doNothing().when(mockLayer).blit(any(Layer.class), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt());
    transformer.transform(layer, properties);
    assertNotNull("Layer constructor was not intercepted.", transformer.layerCreated);
    verify(layer, times(3)).getWidth();
    verify(layer, times(3)).getHeight();
    verify(layer, times(1)).resize(targetWidth, height);
    verify(mockLayer, times(1)).blit(layer, 0, 0, targetWidth, height, 0, 0);
    verifyNoMoreInteractions(layer);
    verifyNoMoreInteractions(mockLayer);
}
Also used : ValueMap(org.apache.sling.api.resource.ValueMap) ValueMapDecorator(org.apache.sling.api.wrappers.ValueMapDecorator) Layer(com.day.image.Layer) Test(org.junit.Test)

Example 4 with Layer

use of com.day.image.Layer in project acs-aem-commons by Adobe-Consulting-Services.

the class ProgressiveJpegTest method writeProgressiveImage.

private static byte[] writeProgressiveImage(BufferedImage image) throws IOException {
    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
    Layer layer = new Layer(image);
    ProgressiveJpeg.write(layer, 1, byteOut);
    return byteOut.toByteArray();
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) Layer(com.day.image.Layer)

Example 5 with Layer

use of com.day.image.Layer in project acs-aem-commons by Adobe-Consulting-Services.

the class ProgressiveJpegTest method createExpectedImage.

private static BufferedImage createExpectedImage(BufferedImage image) throws IOException {
    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
    Layer layer = new Layer(image);
    layer.write("image/jpeg", 1, byteOut);
    return ImageIO.read(new ByteArrayInputStream(byteOut.toByteArray()));
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Layer(com.day.image.Layer)

Aggregations

Layer (com.day.image.Layer)29 ValueMap (org.apache.sling.api.resource.ValueMap)10 Test (org.junit.Test)10 ValueMapDecorator (org.apache.sling.api.wrappers.ValueMapDecorator)9 InputStream (java.io.InputStream)5 Resource (org.apache.sling.api.resource.Resource)4 Rendition (com.day.cq.dam.api.Rendition)3 Color (java.awt.Color)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 Asset (com.day.cq.dam.api.Asset)2 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)2 BufferedImage (java.awt.image.BufferedImage)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 MockSlingHttpServletRequest (org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest)2 MockSlingHttpServletResponse (org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse)2 NamedImageTransformer (com.adobe.acs.commons.images.NamedImageTransformer)1 WorkflowHelper (com.adobe.acs.commons.util.WorkflowHelper)1 AbstractImageTest (com.adobe.cq.wcm.core.components.internal.models.v1.AbstractImageTest)1 DownloadResource (com.day.cq.commons.DownloadResource)1 ImageResource (com.day.cq.commons.ImageResource)1