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>
----------------------------------------------------------------

Reply via email to