Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 ImageIO reads JPEG incorrectly in Linux

I'm trying to read user-uploaded JPEG image (arbitrary) to create thumbnail in server app. System works just fine in Windows7 / Oracle Java 8u11 but I have problem with color model under CentOS on server:

original image is:

http://studio-st.ru/media/portfolio/image/45

resulting thumbnail on development workstation under Windows is absolutely correct

result under Linux is color-shifted (reddish on Java 8u05, color-shifted on Java 8u11). Not presented here because original example was on site, which is fixed now.

Deeper investigation shown that problem is in reading image - ImageIO.read(inputStream) on Windows and Linux return image objects with exactly the same parameters, however color probe getRGB(x,y) for the same image (just read) returns different values.

Colors treating in Linux differ on Java 8u05 & 8u11, 8u05 was "reddish", 8u11 is as shown above.

This has nothing to do with alpha channels - this particular source image is JPEG Type 5 (TYPE_3BYTE_BGR), exported from Adobe Lightroom with conversion to sRGB, without any other tricks.

This also affects all images exported that time (all images on this site, in fact).

Can anyone provide some advice on how to make it work (except for waiting for fix for JDK)? Maybe recommend alternate library, which can be used here (EJB, data stored in MongoDB, so data is fetched using InputStreams - no filesystem access).

Thanks!

UPD: issue appears to be with Java8's new Color Management Module - it doesn't understand this image format. Switching to legacy CMM fixed the issue. Please see details in correct comment below.

like image 944
Alexander Terekhov Avatar asked Aug 07 '14 16:08

Alexander Terekhov


1 Answers

You could try using my JPEGImageReader plugin for ImageIO, it handles color conversions a little bit differently than the default JPEGImageReader, so it might help (sorry, don't have my work computer near, so I can't test myself just now). If it doesn't help, I'd like to fix it. Can I use your image for a test case? :-)

Another thing that might help, is specifying:

-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider

on the command line (or set the sun.java2d.cmm system property accordingly using other means). The color management module (CMM) was switched from Sun/Kodak's legacy CMM to the more up-to-date and open-source Little CMS in Java 8. Setting this system property will re-enable the legacy color management from Java pre 8.

As you mention no disk access, it pretty much rules out JMagick or im4j as these works best with files. It would probably be possible to use temp files though.

like image 153
Harald K Avatar answered Sep 22 '22 01:09

Harald K