Search in sources :

Example 1 with Thumbnail

use of org.structr.web.common.ImageHelper.Thumbnail in project structr by structr.

the class Image method getScaledImage.

/**
 * Get (down-)scaled image of this image
 *
 * If no scaled image of the requested size exists or the image is newer than the scaled image, create a new one.
 *
 * Default behaviour is to make the scaled image complete fit inside a rectangle of maxWidth x maxHeight.
 *
 * @param maxWidth
 * @param maxHeight
 * @param cropToFit if true, scale down until the shorter edge fits inside the rectangle, and then crop
 *
 * @return scaled image
 */
public static Image getScaledImage(final Image thisImage, final int maxWidth, final int maxHeight, final boolean cropToFit) {
    final Class<Relation> thumbnailRel = StructrApp.getConfiguration().getRelationshipEntityClass("ImageTHUMBNAILImage");
    final Iterable<Relation> thumbnailRelationships = thisImage.getOutgoingRelationships(thumbnailRel);
    final SecurityContext securityContext = thisImage.getSecurityContext();
    final List<Image> oldThumbnails = new LinkedList<>();
    Image thumbnail = null;
    final Image originalImage = thisImage;
    final Integer origWidth = originalImage.getWidth();
    final Integer origHeight = originalImage.getHeight();
    final Long currentChecksum = originalImage.getChecksum();
    Long newChecksum = 0L;
    if (currentChecksum == null || currentChecksum == 0) {
        try {
            newChecksum = FileHelper.getChecksum(originalImage.getFileOnDisk());
            if (newChecksum == null || newChecksum == 0) {
                logger.warn("Unable to calculate checksum of {}", originalImage.getName());
                return null;
            }
        } catch (IOException ex) {
            logger.warn("Unable to calculate checksum of {}: {}", originalImage.getName(), ex.getMessage());
        }
    } else {
        newChecksum = currentChecksum;
    }
    // Read Exif and GPS data from image and update properties
    ImageHelper.getExifData(originalImage);
    // Return self if SVG image
    final String _contentType = thisImage.getContentType();
    if (_contentType != null && (_contentType.startsWith("image/svg") || (_contentType.startsWith("image/") && _contentType.endsWith("icon")))) {
        return thisImage;
    }
    if (origWidth != null && origHeight != null && thumbnailRelationships != null) {
        for (final Relation r : thumbnailRelationships) {
            final Integer w = r.getProperty(StructrApp.key(Image.class, "width"));
            final Integer h = r.getProperty(StructrApp.key(Image.class, "height"));
            if (w != null && h != null) {
                // orginal image is equal or smaller than requested size
                if (((w == maxWidth) && (h <= maxHeight)) || ((w <= maxWidth) && (h == maxHeight)) || ((origWidth <= w) && (origHeight <= h))) {
                    thumbnail = (Image) r.getTargetNode();
                    // Use thumbnail only if checksum of original image matches with stored checksum
                    final Long storedChecksum = r.getProperty(StructrApp.key(Image.class, "checksum"));
                    if (storedChecksum != null && storedChecksum.equals(newChecksum)) {
                        return thumbnail;
                    } else {
                        oldThumbnails.add(thumbnail);
                    }
                }
            }
        }
    }
    if (originalImage.getIsCreatingThumb()) {
        logger.debug("Another thumbnail is being created - waiting....");
    } else {
        try {
            // No thumbnail exists, or thumbnail was too old, so let's create a new one
            logger.debug("Creating thumbnail for {} (w={} h={} crop={})", new Object[] { getName(), maxWidth, maxHeight, cropToFit });
            originalImage.unlockSystemPropertiesOnce();
            originalImage.setIsCreatingThumb(true);
            final App app = StructrApp.getInstance();
            originalImage.unlockSystemPropertiesOnce();
            originalImage.setProperty(StructrApp.key(File.class, "checksum"), newChecksum);
            final Thumbnail thumbnailData = ImageHelper.createThumbnail(originalImage, maxWidth, maxHeight, cropToFit);
            if (thumbnailData != null) {
                final Integer tnWidth = thumbnailData.getWidth();
                final Integer tnHeight = thumbnailData.getHeight();
                byte[] data = null;
                try {
                    data = thumbnailData.getBytes();
                    final String thumbnailName = ImageHelper.getThumbnailName(originalImage.getName(), tnWidth, tnHeight);
                    // create thumbnail node
                    thumbnail = ImageHelper.createImageNode(securityContext, data, "image/" + Thumbnail.defaultFormat, Image.class, thumbnailName, true);
                } catch (IOException ex) {
                    logger.warn("Could not create thumbnail image for " + getUuid(), ex);
                }
                if (thumbnail != null && data != null) {
                    // Create a thumbnail relationship
                    final PropertyMap relProperties = new PropertyMap();
                    relProperties.put(StructrApp.key(Image.class, "width"), tnWidth);
                    relProperties.put(StructrApp.key(Image.class, "height"), tnHeight);
                    relProperties.put(StructrApp.key(Image.class, "checksum"), newChecksum);
                    app.create(originalImage, thumbnail, thumbnailRel, relProperties);
                    final PropertyMap properties = new PropertyMap();
                    properties.put(StructrApp.key(Image.class, "width"), tnWidth);
                    properties.put(StructrApp.key(Image.class, "height"), tnHeight);
                    properties.put(StructrApp.key(AbstractNode.class, "hidden"), originalImage.getProperty(AbstractNode.hidden));
                    properties.put(StructrApp.key(AbstractNode.class, "visibleToAuthenticatedUsers"), originalImage.getProperty(AbstractNode.visibleToAuthenticatedUsers));
                    properties.put(StructrApp.key(AbstractNode.class, "visibleToPublicUsers"), originalImage.getProperty(AbstractNode.visibleToPublicUsers));
                    properties.put(StructrApp.key(File.class, "size"), Long.valueOf(data.length));
                    properties.put(StructrApp.key(AbstractNode.class, "owner"), originalImage.getProperty(AbstractNode.owner));
                    properties.put(StructrApp.key(File.class, "parent"), originalImage.getParent());
                    properties.put(StructrApp.key(File.class, "hasParent"), originalImage.getProperty(StructrApp.key(Image.class, "hasParent")));
                    thumbnail.unlockSystemPropertiesOnce();
                    thumbnail.setProperties(securityContext, properties);
                    // Delete outdated thumbnails
                    for (final Image tn : oldThumbnails) {
                        app.delete(tn);
                    }
                }
            } else {
                logger.debug("Could not create thumbnail for image {} ({})", getName(), getUuid());
            }
            originalImage.unlockSystemPropertiesOnce();
            originalImage.setIsCreatingThumb(false);
        } catch (FrameworkException fex) {
            logger.warn("Unable to create thumbnail for " + getUuid(), fex);
        }
    }
    return thumbnail;
}
Also used : StructrApp(org.structr.core.app.StructrApp) App(org.structr.core.app.App) FrameworkException(org.structr.common.error.FrameworkException) AbstractNode(org.structr.core.entity.AbstractNode) IOException(java.io.IOException) Thumbnail(org.structr.web.common.ImageHelper.Thumbnail) LinkedList(java.util.LinkedList) Relation(org.structr.core.entity.Relation) PropertyMap(org.structr.core.property.PropertyMap) SecurityContext(org.structr.common.SecurityContext)

Example 2 with Thumbnail

use of org.structr.web.common.ImageHelper.Thumbnail in project structr by structr.

the class ImageConverterCommand method processMessage.

@Override
public void processMessage(final WebSocketMessage webSocketData) {
    final String originalImageId = webSocketData.getId();
    final Map<String, Object> properties = webSocketData.getNodeData();
    final Image originalImage = (Image) getNode(originalImageId);
    final String format = (String) properties.get("format");
    final int width = (int) (long) properties.get("width");
    final int height = (int) (long) properties.get("height");
    final int offsetX = (int) (long) properties.get("offsetX");
    final int offsetY = (int) (long) properties.get("offsetY");
    if (originalImage != null) {
        final Thumbnail thumbnailData = ImageHelper.createCroppedImage(originalImage, width, height, offsetX, offsetY, format);
        if (thumbnailData != null) {
            final Integer tnWidth = thumbnailData.getWidth();
            final Integer tnHeight = thumbnailData.getHeight();
            byte[] data;
            try {
                data = thumbnailData.getBytes();
                final String thumbnailName = ImageHelper.getVariantName(originalImage.getName(), tnWidth, tnHeight, "_cropped_");
                // create image variant
                final Image imageVariant = ImageHelper.createImageNode(originalImage.getSecurityContext(), data, "image/" + Thumbnail.Format.png, Image.class, thumbnailName, false);
                // store in same parent folder
                imageVariant.setParent(originalImage.getParent());
            } catch (IOException | FrameworkException ex) {
                getWebSocket().send(MessageBuilder.status().code(400).message("Could not create converted image for " + originalImageId).build(), true);
            }
        } else {
            getWebSocket().send(MessageBuilder.status().code(400).message("Could not create converted image for " + originalImageId).build(), true);
        }
    } else {
        getWebSocket().send(MessageBuilder.status().code(400).message("No id of the original image given").build(), true);
    }
}
Also used : FrameworkException(org.structr.common.error.FrameworkException) IOException(java.io.IOException) Image(org.structr.web.entity.Image) Thumbnail(org.structr.web.common.ImageHelper.Thumbnail)

Aggregations

IOException (java.io.IOException)2 FrameworkException (org.structr.common.error.FrameworkException)2 Thumbnail (org.structr.web.common.ImageHelper.Thumbnail)2 LinkedList (java.util.LinkedList)1 SecurityContext (org.structr.common.SecurityContext)1 App (org.structr.core.app.App)1 StructrApp (org.structr.core.app.StructrApp)1 AbstractNode (org.structr.core.entity.AbstractNode)1 Relation (org.structr.core.entity.Relation)1 PropertyMap (org.structr.core.property.PropertyMap)1 Image (org.structr.web.entity.Image)1