Loading image from JCR using AbstractLoader will result in adding the alpha value as a color to generated JPGs --------------------------------------------------------------------------------------------------------------
Key: MGNLIMG-100 URL: http://jira.magnolia-cms.com/browse/MGNLIMG-100 Project: Magnolia Imaging Module Issue Type: Bug Components: image operations Affects Versions: 2.2.1 Reporter: Christian Ringele Assignee: Grégory Joseph Priority: Critical Fix For: 2.x Attachments: AbstractLoader.java.patch, Generator.png, OrigImage-PlacedIntoDMS.jpg, out1-works.png, out1-worksNot.jpg Description: Calling an image generator which uses a FromContent (extends AbstractLoader) operation will result in wrong JPGs. If storing PNGs it works fine. As PNGs have a alpha channel, the alpha value is correctly applied. Storing a JPG, it seems as the ImageIO.write() method writes the alpha value as a color and not ignoring it as it should. Reproduce: 1. Import the generator attached to this issue. Just containing one operation, the load operation. 2. Add a test image to DMS. 3. execute this code with correct paths: {code} final ImagingModuleConfig config = (ImagingModuleConfig) ModuleRegistry.Factory.getInstance().getModuleInstance("imaging"); final ImageGenerator generator = config.getGenerators().get("myOperationChainBResize"); Session dmsSession = MgnlContext.getJCRSession("dms"); Node origImage = dmsSession.getNode("/test/orig"); final Content content = info.magnolia.cms.util.ContentUtil.asContent(origImage); final ParameterProvider<Content> parameterProvider = new ContentParameterProvider(new SimpleEqualityContentWrapper(content)); final BufferedImage bufferedImage = generator.generate(parameterProvider); ImageIO.write(bufferedImage, "png", new File("/Users/cringele/Documents/temp_stuff/image-test/create/out1-works.png")); ImageIO.write(bufferedImage, "jpg", new File("/Users/cringele/Documents/temp_stuff/image-test/create/out1-worksNot.jpg")); {code} You can also write the stream back into JCR, the result is the same. So for testing much easier into a file. Source of the problem: info.magnolia.imaging.operations.load.AbstractLoader.apply(BufferedImage, P) {code} if (source != null) { throw new ImagingException("This operation currently does not support overlaying images"); } final BufferedImage loaded = loadSource(filterParams); if (loaded == null) { throw new ImagingException("Could not load image for " + filterParams); } //This line is the source of the problem. Using BufferedImage.TYPE_INT_RGB would work because it wouldn't contain any alpha channel. Of course just for testing applicable. final BufferedImage img = new BufferedImage(loaded.getWidth(), loaded.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); final Graphics2D g = img.createGraphics(); if (backgroundColor != null) { g.setColor(backgroundColor); g.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight())); } g.drawImage(loaded, null, 0, 0); // TODO would this make any difference ? g.drawRenderedImage(loaded, null); g.dispose(); return img; {code} Proof of the problem source: First possibility: Execute this code just passing back the loaded BufferedImage {code} if (source != null) { throw new ImagingException("This operation currently does not support overlaying images"); } final BufferedImage loaded = loadSource(filterParams); if (loaded == null) { throw new ImagingException("Could not load image for " + filterParams); } return loaded; {code} Second possibility: Pass back the created BufferedImage (img) withour loagin the orig image on top. Like this you can compare alpha value in PNG to color in JPG. {code} if (source != null) { throw new ImagingException("This operation currently does not support overlaying images"); } final BufferedImage loaded = loadSource(filterParams); if (loaded == null) { throw new ImagingException("Could not load image for " + filterParams); } final BufferedImage img = new BufferedImage(loaded.getWidth(), loaded.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); final Graphics2D g = img.createGraphics(); if (backgroundColor != null) { g.setColor(backgroundColor); g.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight())); } //Image not loaded on top of it //g.drawImage(loaded, null, 0, 0); // TODO would this make any difference ? g.drawRenderedImage(loaded, null); g.dispose(); return img; {code} It seems to be a known problem: http://stackoverflow.com/questions/8410996/java-bufferedimage-saves-with-unwanted-background-color Trying out the solution they suggest did not work. Was not able to supply a patch with a final solution. Added a pacth as a workaround. -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://jira.magnolia-cms.com/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira ---------------------------------------------------------------- For list details, see: http://www.magnolia-cms.com/community/mailing-lists.html Alternatively, use our forums: http://forum.magnolia-cms.com/ To unsubscribe, E-mail to: <dev-list-unsubscr...@magnolia-cms.com> ----------------------------------------------------------------