Update Image with new image variants programmatically

305 views
Skip to first unread message

singh.bh...@gmail.com

unread,
Jul 19, 2017, 6:39:39 AM7/19/17
to Hippo Community
Hi,

I have defined a custom image set i.e. CustomImageSet with 5-6 variant in it. I have uploaded few images after that and found that all image variants has been created automatically. Now i have added 2 more variants to my imageset but when i checked my image it shows blank content for the new variants. Is there a way i can create the new variants for my already existing images.

Thanks
Bhupendra Singh 

Woonsan Ko

unread,
Jul 24, 2017, 2:33:38 PM7/24/17
to hippo-c...@googlegroups.com
On Wed, Jul 19, 2017 at 4:39 AM, <singh.bh...@gmail.com> wrote:
Hi,

I have defined a custom image set i.e. CustomImageSet with 5-6 variant in it. I have uploaded few images after that and found that all image variants has been created automatically. Now i have added 2 more variants to my imageset but when i checked my image it shows blank content for the new variants. Is there a way i can create the new variants for my already existing images.

If you can write a groovy script or java code which is iterating all those existing image sets, then you might want to use the techniques shown in the following page:

You can create new variant images into temporary files and update those variant node with those.
It's slightly a different use case, but you might want to take a look at the example here, too (content-exim uses gallery-magick component internally as well):

Regards,

Woonsan
 

Thanks
Bhupendra Singh 

--
Hippo Community Group: The place for all discussions and announcements about Hippo CMS (and HST, repository etc. etc.)
 
To post to this group, send email to hippo-community@googlegroups.com
RSS: https://groups.google.com/group/hippo-community/feed/rss_v2_0_msgs.xml?num=50
---
You received this message because you are subscribed to the Google Groups "Hippo Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hippo-community+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/hippo-community.
For more options, visit https://groups.google.com/d/optout.



--
71 Summer Street, 2nd Floor, Boston, MA 02110
Amsterdam - Oosteinde 11, 1017 WT Amsterdam
US +1 877 414 4776 (toll free)
Europe +31(0)20 522 4466

jerr...@gmail.com

unread,
Nov 30, 2017, 1:53:47 PM11/30/17
to Hippo Community
Woonsan,   
  
     I am trying to do something similar and found this thread. I tried the approach using  org.onehippo.forge.gallerymagick.core.command.ScalrProcessorUtils  from Groovy, but get a security exception: "Caused by: java.lang.SecurityException: Importing [java.io.File] is not allowed

    It appears all the Hippo utilities take java.io.File and never inputstreams. I can get an inputstream from the imagegallery node's jcr:data property but can't use GroovyUpdaterEditor to create a file with it to use these utilities. Any chance there might be underlying methods that use an inputstream and return an outputstream that can be placed back on a jcr:data property?

Thanks
Jerry

On Monday, July 24, 2017 at 2:33:38 PM UTC-4, woonsan.ko wrote:
On Wed, Jul 19, 2017 at 4:39 AM, <singh.bh...@gmail.com> wrote:
Hi,

I have defined a custom image set i.e. CustomImageSet with 5-6 variant in it. I have uploaded few images after that and found that all image variants has been created automatically. Now i have added 2 more variants to my imageset but when i checked my image it shows blank content for the new variants. Is there a way i can create the new variants for my already existing images.

If you can write a groovy script or java code which is iterating all those existing image sets, then you might want to use the techniques shown in the following page:

You can create new variant images into temporary files and update those variant node with those.
It's slightly a different use case, but you might want to take a look at the example here, too (content-exim uses gallery-magick component internally as well):

Regards,

Woonsan
 

Thanks
Bhupendra Singh 

--
Hippo Community Group: The place for all discussions and announcements about Hippo CMS (and HST, repository etc. etc.)
 
To post to this group, send email to hippo-c...@googlegroups.com

RSS: https://groups.google.com/group/hippo-community/feed/rss_v2_0_msgs.xml?num=50
---
You received this message because you are subscribed to the Google Groups "Hippo Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hippo-communi...@googlegroups.com.

Woonsan Ko

unread,
Nov 30, 2017, 2:12:45 PM11/30/17
to hippo-c...@googlegroups.com
Hi Jerry,

Please see my comments inline.

On Thu, Nov 30, 2017 at 1:53 PM, <jerr...@gmail.com> wrote:
Woonsan,   
  
     I am trying to do something similar and found this thread. I tried the approach using  org.onehippo.forge.gallerymagick.core.command.ScalrProcessorUtils  from Groovy, but get a security exception: "Caused by: java.lang.SecurityException: Importing [java.io.File] is not allowed

Yes, hippo groovy engine has some blacklist classes *by checking the types in the script source*, but it's not checking a runtime object, which is the trick.
You can use VFS library and its FileObject class instead as shown in the example [1]:
Or, you can simply use Content EXIM library [1] to do that because it has several utilities already to import/export hippo binary assets/galleries, etc.
Also, see the javadocs such as [2] too.

 

    It appears all the Hippo utilities take java.io.File and never inputstreams. I can get an inputstream from the imagegallery node's jcr:data property but can't use GroovyUpdaterEditor to create a file with it to use these utilities. Any chance there might be underlying methods that use an inputstream and return an outputstream that can be placed back on a jcr:data property?

Content EXIM provides some workaround utilities already. You will find almost everything there from javadocs and example.

Regards,

Woonsan
 
To post to this group, send email to hippo-community@googlegroups.com

RSS: https://groups.google.com/group/hippo-community/feed/rss_v2_0_msgs.xml?num=50
---
You received this message because you are subscribed to the Google Groups "Hippo Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hippo-community+unsubscribe@googlegroups.com.
US +1 877 414 4776 (toll free)
Europe +31(0)20 522 4466



jerr...@gmail.com

unread,
Nov 30, 2017, 2:57:24 PM11/30/17
to Hippo Community
Thanks Woonsan. I wound up going native java/awt to avoid File. I have something working that I just need to fiddle with. Here is the groovy:

package org.hippoecm.frontend.plugins.cms.admin.updater

import org.onehippo.repository.update.BaseNodeUpdateVisitor
import javax.jcr.Node
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.imageio.ImageIO;

class UpdaterTemplate extends BaseNodeUpdateVisitor {

  int width;
  int height;
  
  boolean doUpdate(Node node) {
    if (!"oakwood:PropertyImageSet".equals(node.getPrimaryNodeType().getName())) return false;
    log.debug "Updating node ${node.path}"
    java.io.InputStream is = node.getNode("hippogallery:original").getProperty("jcr:data").getValue().getBinary().getStream();
    
    
    Node thumbnail = node.getNode("hippogallery:thumbnail");
Node newNode = node.addNode("hippogallery:sample","hippogallery:image");
newNode.setProperty("jcr:mimeType", thumbnail.getProperty("jcr:mimeType").getValue());
    newNode.setProperty("hippogallery:height", this.height);
    newNode.setProperty("hippogallery:width", this.width);
    newNode.setProperty("jcr:lastModified", new java.util.GregorianCalendar());
     
String formatName = thumbnail.getProperty("jcr:mimeType").getValue().getString().replaceAll(".*/", "");
    is = resize(is, 100, 100, formatName)
    log.debug "resized"
    
newNode.setProperty("jcr:data",is);
    
    return true;
  }

  boolean undoUpdate(Node node) {
    throw new UnsupportedOperationException('Updater does not implement undoUpdate method')
  }
  
  public InputStream resize(InputStream is,
            int scaledWidth, int scaledHeight, String formatName)
            throws IOException {
        // reads input image
        BufferedImage inputImage = ImageIO.read(is);
 
        // creates output image
        BufferedImage outputImage = new BufferedImage(scaledWidth,
                scaledHeight, inputImage.getType());
 
        // scales the input image to the output image
        Graphics2D g2d = outputImage.createGraphics();
        g2d.drawImage(inputImage, 0, 0, scaledWidth, scaledHeight, null);
        g2d.dispose();
 
        
        // writes to output file
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(outputImage, formatName, os);
        InputStream returnIs = new ByteArrayInputStream(os.toByteArray());
              
        this.height = outputImage.getHeight();
        this.width = outputImage.getWidth();
        return returnIs;

jerr...@gmail.com

unread,
Nov 30, 2017, 5:00:17 PM11/30/17
to Hippo Community
After some tips from Woonsan I go a variation working that uses the ScalrProcessorUtils. In this version I'm hard-coding the new target size to 100x100 but then reading the resulting rescaled image for the true height.

package org.hippoecm.frontend.plugins.cms.admin.updater

import org.onehippo.repository.update.BaseNodeUpdateVisitor
import javax.jcr.Node
import java.awt.Graphics2D;
import org.apache.jackrabbit.value.BinaryValue
import org.onehippo.forge.content.exim.core.util.ContentFileObjectUtils
import org.onehippo.forge.gallerymagick.core.command.ScalrProcessorUtils
import org.onehippo.forge.gallerymagick.core.ImageDimension
import org.onehippo.forge.content.pojo.model.ContentPropertyType


class UpdaterTemplate extends BaseNodeUpdateVisitor {

  
  boolean doUpdate(Node node) {
    if (!"oakwood:PropertyImageSet".equals(node.getPrimaryNodeType().getName())) return false;
    log.debug "Updating node ${node.path}"
    java.io.InputStream is = node.getNode("hippogallery:original").getProperty("jcr:data").getValue().getBinary().getStream();
    
    
    Node thumbnail = node.getNode("hippogallery:thumbnail");
Node newNode = node.addNode("hippogallery:sample","hippogallery:image");
newNode.setProperty("jcr:mimeType", thumbnail.getProperty("jcr:mimeType").getValue());
    newNode.setProperty("jcr:lastModified", new java.util.GregorianCalendar());
     
String formatName = thumbnail.getProperty("jcr:mimeType").getValue().getString().replaceAll(".*/", "");
    resize(node.getNode("hippogallery:original"),newNode, 100, 100, formatName)
    log.debug "resized"
    
    
    return true;
  }

  boolean undoUpdate(Node node) {
    throw new UnsupportedOperationException('Updater does not implement undoUpdate method')
  }
  
  public void resize(Node original, Node resized,
            int scaledWidth, int scaledHeight, String formatName)
            throws IOException {
def newFile = ContentFileObjectUtils.createTempFile(original.getName(), "."+formatName);
def oldFile = ContentFileObjectUtils.createTempFile(original.getName(), "."+formatName);
//put the original in a file
OutputStream os = oldFile.getContent().getOutputStream();
InputStream is = original.getProperty("jcr:data").getValue().getBinary().getStream();
byte[] buffer = new byte[is.available()];
is.read(buffer);
os.write(buffer);
is.close();
os.close();
        ScalrProcessorUtils.resizeImage(ContentFileObjectUtils.toFile(oldFile), ContentFileObjectUtils.toFile(newFile), 
                                        ImageDimension.from(scaledWidth+"x"+scaledHeight))
        
        resized.setProperty("jcr:data", newFile.getContent().getInputStream())
        
        def dimension = ScalrProcessorUtils.identifyDimension(ContentFileObjectUtils.toFile(newFile))
                                                                    
        resized.setProperty("hippogallery:height", dimension.getHeight())
        resized.setProperty("hippogallery:width", dimension.getWidth())

Jeroen Hoffman

unread,
Dec 1, 2017, 4:29:11 AM12/1/17
to hippo-c...@googlegroups.com
Hi,

For regenerating image sets, I think it would be easy to re-use the script that is embedded in the essentials Gallery Manager, at

--
Hippo Community Group: The place for all discussions and announcements about Hippo CMS (and HST, repository etc. etc.)
 
To post to this group, send email to hippo-community@googlegroups.com

RSS: https://groups.google.com/group/hippo-community/feed/rss_v2_0_msgs.xml?num=50
---
You received this message because you are subscribed to the Google Groups "Hippo Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hippo-community+unsubscribe@googlegroups.com.

jerr...@gmail.com

unread,
Dec 1, 2017, 9:17:54 AM12/1/17
to Hippo Community
Thanks Jeroen, that is very useful. It looks like that will dynamically handle all the image sets, I will test that out. 
To post to this group, send email to hippo-c...@googlegroups.com

RSS: https://groups.google.com/group/hippo-community/feed/rss_v2_0_msgs.xml?num=50
---
You received this message because you are subscribed to the Google Groups "Hippo Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hippo-communi...@googlegroups.com.

Brian Snijders

unread,
Dec 8, 2017, 3:26:46 AM12/8/17
to hippo-c...@googlegroups.com
Hi guys,

Just to jump in a bit as I saw this thread coming by and recognised the same challenge as I've had before. I haven't checked your script Jeroen, but in the past I've managed to rescale existing images and create new variants by instantiating a ScalingGalleryProcessor, providing scaling parameters of the desired image dimensions to it as a constructor argument. The actual implementation can be found in "org.hippoecm.frontend.plugins.gallery.processor.ScalingGalleryProcessor" and from there on you should be able to write a Groovy Script using the SGP.

I can imagine, without having checked it, that the Essentials script follows the same path. If so, then my reply is just a real world confirmation that you can actually use the SGP for this issue succesfully. 
@Jerry, the SGP will also able operate on streamed data; your route on streamed data is the same as I did in the past, so it should work :).

Cheers,
Brian

To post to this group, send email to hippo-community@googlegroups.com

RSS: https://groups.google.com/group/hippo-community/feed/rss_v2_0_msgs.xml?num=50
---
You received this message because you are subscribed to the Google Groups "Hippo Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hippo-community+unsubscribe@googlegroups.com.



--

Brian Snijders
Consultant online

t:  +31102020544
m:  +31645540083
w:  www.incentro.com

rotterdam office | van nelle ontwerpfabriek
van nelleweg 2429  |  3044 bc  |  rotterdam

incentro


Reply all
Reply to author
Forward
0 new messages