[MGNLIMG-100] Loading image from JCR using AbstractLoader will result in adding the alpha value as a color to generated JPGs Created: 01/Nov/12 Updated: 09/Jul/13 Resolved: 05/Dec/12 |
|
| Status: | Closed |
| Project: | Imaging |
| Component/s: | image operations |
| Affects Version/s: | 2.2.1 |
| Fix Version/s: | 2.2.2 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Christian Ringele | Assignee: | Roman Kovařík |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
||||||||
| Issue Links: |
|
||||||||
| Template: |
|
||||||||
| Patch included: |
Yes
|
||||||||
| Acceptance criteria: |
Empty
|
||||||||
| Task DoD: |
[ ]*
Doc/release notes changes? Comment present?
[ ]*
Downstream builds green?
[ ]*
Solution information and context easily available?
[ ]*
Tests
[ ]*
FixVersion filled and not yet released
[ ] 
Architecture Decision Record (ADR)
|
||||||||
| Bug DoR: |
[ ]*
Steps to reproduce, expected, and actual results filled
[ ]*
Affected version filled
|
||||||||
| Date of First Response: | |||||||||
| Description |
|
Description: Reproduce: 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")); 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: 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; Proof of the problem source: 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; Second possibility: Pass back the created BufferedImage (img) withour loagin the orig image on top. 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; It seems to be a known problem: Was not able to supply a patch with a final solution. Added a pacth as a workaround. |
| Comments |
| Comment by Christian Ringele [ 01/Nov/12 ] |
|
Look at the non working image with Gimp or Photoshop. |
| Comment by Tobias Mattsson [ 01/Nov/12 ] |
|
Opening out1-worksNot.jpg shows it with psychedelic colors in chrome and firefox while its black in safari, preview and seashore. |
| Comment by Tobias Mattsson [ 01/Nov/12 ] |
|
The output image is a CMYK jpeg while the input is an RGB jpeg. There's a special case variant of jpeg that uses the four channel CMYK to store what is effectively an RGBA jpeg, seems very hackish. |
| Comment by Tobias Mattsson [ 01/Nov/12 ] |
|
Possible its not a cmyk image, just a four channel jpeg which is then assumed to be cmyk because of the four channels. If you draw it onto an RGB bufferedImage and then save that; does that result in an RGB image that is correct? |
| Comment by Christian Ringele [ 01/Nov/12 ] |
|
using BufferedImage.TYPE_INT_RGB to create the image. |
| Comment by Tobias Mattsson [ 01/Nov/12 ] |
|
Output-using-BufferedImage.TYPE_INT_RGB.jpg is an RGB jpeg and looks correct in all the apps i have on my machine. |
| Comment by Tobias Mattsson [ 01/Nov/12 ] |
|
Okay, found this in the JRE bug database, http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4836466, closed as not a bug. This question on stackoverflow describes the same problem and shows images with the same problems as we're having. The solution is to save a BufferedImage without alpha. |
| Comment by Christian Ringele [ 04/Nov/12 ] |
|
The problem is, that on the moment of loading the original image, it is unknown as what format the target image will be saved. |
| Comment by Jan Haderka [ 05/Dec/12 ] |
|
Any reason to not use tools for creating compatible images that already exist? Like e.g. org.jdesktop.swingx.graphics.GraphicsUtilities.createColorModelCompatibleImage(BufferedImage image) should be in maven repo - http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22swingx-core%22 |
| Comment by Roman Kovařík [ 05/Dec/12 ] |
|
The utils form GraphicsUtilities (createCompatibleImage or createColormodelCompatibleImage) cause failing of some other tests. When source images are of type TYPE_CUSTOM, the target will be TYPE_CUSTOM too. That produces Unknows image type later... int imageType = loaded.getType(); //set the output image type to the source image type
if (imageType == BufferedImage.TYPE_CUSTOM) { //if the source image type is not set...
if ( loaded.getAlphaRaster() != null ) { //with alpha channel
imageType = BufferedImage.TYPE_INT_ARGB_PRE;
} else { //without alpha channel
imageType = BufferedImage.TYPE_INT_RGB;
}
}
|