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;
}
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);
}
}
Aggregations