8

I'm using (org.imgscalr.Scalr) libraries to resize some images, but when after resizing the background turns red . My code is:

BufferedImage imagemPng = ImageIO.read(image);
BufferedImage imagemJpg = Scalr.resize(imagemPng, Method.QUALITY, 1920, 937);

can you help me?

Thank you

Felix Glas
  • 15,065
  • 7
  • 53
  • 82

1 Answers1

19

The remainder of the code you omitted (the ImageIO save) and if the PNG you are reading in has a transparent channel or not (as @Daft Punk pointed out) are the important bits here.

I am willing to bet $1 that your PNG has an alpha channel in it and JPG does not support alpha; unfortunately Java's JPG encoder does not know to ignore the Alpha channel on a BufferedImage you pass in and it will discard one of the REAL color channels (R/G/B) in favor of writing out the alpha values instead of one of those color channels.

For example, if you have:

ARGB

The Java JPG encoder will write out the following 3 channels thinking they are RGB:

[ARG]

and discard the BLUE channel.

Fortunately, the fix is dead simple. Just create a new BufferedImage of type TYPE_INT_RGB like so:

BufferedImage imageToSave = new BufferedImage(imagemJpg.getWidth(), imagemJpg.getHeight(), BufferedImage.TYPE_INT_RGB);

then you need to "render" the BufferedImage with an Alpha channel to it, to strip the Alpha channel:

Graphics g = imageToSave.getGraphics();
g.drawImage(imagemJpg, 0, 0, null);

Now you can save out the resulting imageToSave image as a JPG and it will look fine.

TIP: Don't forget, if you don't like the way the image looks (blurry, artifacted, etc.) you need to pass arguments directly to the Java JPG encoder to tell it to not compress so much (read this) -- This is rarely an issue, but it has come up in the past when people say "imgscalr looks bad!" -- turns out the BufferedImage is really nice and sharp, but the Java encoder is too aggressively compressing the result.

I've been meaning to address these little annoying gotcha's with Java images by adding some additional IO helpers to the imgscalr library so you can just load files and save them and not worry about these nitty gritty details.

Riyad Kalla
  • 10,604
  • 7
  • 53
  • 56
  • You are expert in this issue. The problem was when I converted the image from png to jpg, but now the problem was resolved. I learned a lot with this mistake. Thank you so much!!! – Rafael Pereira Delfino Jul 23 '13 at 18:35
  • HI @RiyadKalla, I am facing a similar issue. I tried debugging it by checking for the alpha channel on the original image, but it always returns false. I have same application deployed on two servers with same Java and OS and one application always produces the colored background and the other produces the correct resized image. When I restart tomcat it fixes the issue. It is getting really hard for me to understand why is this happening. Can you please provide any insights if possible. Thanks. – Shriram Sharma May 16 '16 at 16:31
  • @ShriramSharma Ugh... that's tricky... I guess the good news is that it sounds _most likely_ to be an environment issue... meaning something about the version of JDK/JRE running Tomcat or Tomcat itself might be a bit diff... if you can exactly match the two systems you should be good to go. Also if the test images are different that might cause that... channel order is not firmly defined... an image can be ARGB or RGBA for example... so if you are using different images it's possible they have alpha channels it's just that when one gets culled it's fine and when the other gets culled, no good. – Riyad Kalla Aug 11 '16 at 17:35
  • this issue discusses this problem beside a proposed solution. https://github.com/rkalla/imgscalr/issues/82 – Amin Heydari Alashti Jun 02 '19 at 07:38