17

Apologies for the somewhat vague title, I can't work out what the keywords are here. The setup's quite simple, I'm opening an image with

ImageIO.read(new File(filename));

This works for most files, however for one I get an IllegalArgumentException with the detail: "numbers of source Raster bands and source color space components do not match". This image was obtained via wget on a valid Flickr URL, and I've used other images obtained this way, so the method for obtaining images seems sound in principle. I'm not sure what's causing the exception.

A workaround would be more than acceptable - I'm not fussed with using ImageIO in particular, and the image looks fine visually. I just need to get it being read without Java freaking out!

Here's the image in question, in case it's of any use:

enter image description here

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
mtrc
  • 1,317
  • 3
  • 16
  • 39
  • I get the same error (at least when using `ImageIO.read(new URL("http://i.imgur.com/rC6Jk.jpg"));`). Is this the only B/W image you are processing? – Moritz Petersen May 02 '12 at 15:12
  • Hard to say - the nature of the image retrieval process is very undirected (the idea is that the software is autonomous!) It's the only one with such low saturation though. Do you think that's the cause? – mtrc May 02 '12 at 15:25
  • Have you found any solution for this? – matt b Jun 21 '12 at 18:46
  • Nope. I've had to rely on the fact that other images will be found if this error is raised. – mtrc Jun 22 '12 at 20:37

3 Answers3

12

So I was having this same issue and found that the image was gray-scale and that the default ImageIO.read implementation was not figuring that out because the image metadata wasn't quite as expected. I wrote a work around that retries the load as 'BufferedImage.TYPE_BYTE_GRAY' if it fails the main load.

            Iterator<ImageReader> iter = ImageIO.getImageReaders(stream);

        Exception lastException = null;
        while (iter.hasNext()) {
            ImageReader reader = null;
            try {
                reader = (ImageReader)iter.next();
                ImageReadParam param = reader.getDefaultReadParam();
                reader.setInput(stream, true, true);
                Iterator<ImageTypeSpecifier> imageTypes = reader.getImageTypes(0);
                while (imageTypes.hasNext()) {
                    ImageTypeSpecifier imageTypeSpecifier = imageTypes.next();
                    int bufferedImageType = imageTypeSpecifier.getBufferedImageType();
                    if (bufferedImageType == BufferedImage.TYPE_BYTE_GRAY) {
                        param.setDestinationType(imageTypeSpecifier);
                        break;
                    }
                }
                bufferedImage = reader.read(0, param);
                if (null != bufferedImage) break;
            } catch (Exception e) {
                lastException = e;
            } finally {
                if (null != reader) reader.dispose();               
            }
        }
        // If you don't have an image at the end of all readers
        if (null == bufferedImage) {
            if (null != lastException) {
                throw lastException;
            }
        }
Tate Moore
  • 136
  • 2
  • 3
  • 1
    The beauty of SO: A problem that would have taken me two hours to figure out now takes 10 minutes. Thank you, Tate Moore. – charleslparker Jul 23 '12 at 23:08
  • Wonderful stuff! Never thought anyone would come back and knock this one down but you did! Lovely stuff. – mtrc Jul 27 '12 at 19:03
  • when I use this solution after it fails with ImageIO.read(InputStream) it does not execute the rest of the code (while (iter.hasNext()) is false), but if I omit ImageIO.read(InputStream) part it does the job. What is wrong with my code? – user1052958 Aug 28 '12 at 20:45
  • +1 because it works on some gray-scale cases, not working with ImageIO.read(...). But note, this code forces image load as gray-scale, even if it's not. Yout have to make first a ImageIO.read(...) & if it fails, use this method. – surfealokesea Feb 18 '15 at 07:08
  • In case anyone is wondering how to get that `stream`, if can be created by using `ImageIO.createImageInputStream(InputStream)` (this argument can be `FileInputStream`, `ByteArrayInputStream` etc). – Carcamano Feb 18 '16 at 18:45
4

The error message is informative and indicates that the number of raster bands, as mentioned in the ICC color profile, seems to be incorrect. I used ImageMagick to strip the ICC profile from the image. ImageIO subsequently has no problems reading the images (~1k bad images). Hope that helps.

Suchet
  • 206
  • 1
  • 4
  • It did! Thanks. I definitely think the message is informative, it's just above my level of understanding, not their fault. Thanks for commenting :) – mtrc Apr 07 '13 at 12:53
2

It is possible to read this image using twelvemonkeys ImageIO, which is a more robust and forgiving replacement for the original ImageIO provided by the JRE.

See https://github.com/haraldk/TwelveMonkeys/

I found this solution in the PDF Box Jira https://issues.apache.org/jira/browse/PDFBOX-3637

In order to use twelvemonkeys, it is sufficient to add it as a maven dependency. It then registers itself before the default image processor.

<dependency>
    <groupId>com.twelvemonkeys.imageio</groupId>
    <artifactId>imageio-jpeg</artifactId>
    <version>3.3.2</version> <!-- Alternatively, build your own version -->
</dependency>
Hok
  • 847
  • 8
  • 16