Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numbers of source Raster bands and source color space components do not match when i read image [duplicate]

When I try to read an image using the following code

myPicture = ImageIO.read(new File("./src/javaassignment1b/Deck/Ace_Diamond_1.jpg"));

I get the following error

 Numbers of source Raster bands and source color space components do not match

On researching , there is a similar question and it appears its an issue with my JPEG image(It was cropped from a bigger picture which may have caused the error) and i have to work around the grayscale issue with I have no idea what it is about or how to implement it.

NOTE : At first i tried using ImageIcon to add to JPanel but it could not work hence i found this solution which lead to my current problem. I just starting programming in Java.

EDIT: Here are the link to the images and I am doing a Java Application

I need an alternative to add a image to a JPanel.

like image 580
Computernerd Avatar asked Apr 20 '14 11:04

Computernerd


2 Answers

This question has already been answered here: https://stackoverflow.com/a/18400559/1042999 and this is a very elegant solution to the problem. The solution involves using a plugin for ImageIO with implemented support for multiple formats that are not supported by the default ImageIo implementation. Details on how to use the plugin in regular java apps, and servlet containers can be found: https://github.com/haraldk/TwelveMonkeys

like image 187
Sinisha Mihajlovski Avatar answered Nov 15 '22 15:11

Sinisha Mihajlovski


Open the images with any image viewer/editor, and save them in a "standard" format

I wonder how the images have been created in the first place. My guess would be that you have used some fancy, sophisticated image manipulation program for the "cropping" that you mentioned, and that this program allows storing images in some unusual formats, and that you did (or did not) modify some options that have been available when saving the image, not knowing wha exactly these options meant (apologies if I underestimate your familiarity with image formats and color spaces here...).

However, the reason for the problem is that the images are stored with some strange form of an YPbPr or YCbCr color space (I did not manage to figure out that one exactly, but they are both not supported in ImageIO by default).

Neither of my attempts to apply the standard color conversions for YPbPb->RGB or YCbCb->RGB seemed to reproduce the exact original colors, but as you might notice when skimming over the Wikipedia articles: Quite some academic steam was let off in the world of color spaces....

Again: I'd strongly recommend you to open the images with any image viewer/editor, and save them in a "standard" format. And preferably as a PNG, because JPG is not really suitable for these kinds of images. JPG is more intended for "natural" images, like photos. For such "artificial" images, the compression must be very low to avoid artifacts.

However, this program shows the image with nearly correct colors, but the color conversion still seems to be not entirely correct.

import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class StrangeImageTest
{
    public static void main(String[] args) throws IOException
    {
        final BufferedImage image = readImage(new File("Ace_Diamond_1.jpg"));

        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame f = new JFrame();
                f.getContentPane().add(new JLabel(new ImageIcon(image)));
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }

    static BufferedImage readImage(File file) throws IOException
    {
        return readImage(new FileInputStream(file));
    }

    static BufferedImage readImage(InputStream stream) throws IOException
    {
        Iterator<ImageReader> imageReaders = 
            ImageIO.getImageReadersBySuffix("jpg");
        ImageReader imageReader = imageReaders.next();
        ImageInputStream iis = 
            ImageIO.createImageInputStream(stream);
        imageReader.setInput(iis, true, true);
        Raster raster = imageReader.readRaster(0, null);
        int w = raster.getWidth();
        int h = raster.getHeight();

        BufferedImage result = 
            new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        int rgb[] = new int[3];
        int pixel[] = new int[3];
        for (int x=0; x<w; x++)
        {
            for (int y=0; y<h; y++)
            {
                raster.getPixel(x, y, pixel);
                int Y = pixel[0];
                int CR = pixel[1];
                int CB = pixel[2];
                toRGB(Y, CB, CR, rgb);
                int r = rgb[0];
                int g = rgb[1];
                int b = rgb[2];
                int bgr = 
                    ((b & 0xFF) << 16) | 
                    ((g & 0xFF) <<  8) | 
                     (r & 0xFF);
                result.setRGB(x, y, bgr);
            }
        }
        return result;
    }

    // Based on http://www.equasys.de/colorconversion.html
    private static void toRGB(int y, int cb, int cr, int rgb[])
    {
        float Y = y / 255.0f;
        float Cb = (cb-128) / 255.0f;
        float Cr = (cr-128) / 255.0f;

        float R = Y + 1.4f * Cr;
        float G = Y -0.343f * Cb - 0.711f * Cr;
        float B = Y + 1.765f * Cb;

        R = Math.min(1.0f, Math.max(0.0f, R));
        G = Math.min(1.0f, Math.max(0.0f, G));
        B = Math.min(1.0f, Math.max(0.0f, B));

        int r = (int)(R * 255);
        int g = (int)(G * 255);
        int b = (int)(B * 255);

        rgb[0] = r;
        rgb[1] = g;
        rgb[2] = b;
    }
}

(Note: This could be implemented much simpler, with a ColorConvertOp that converts into the RGB color space from the color space that was used for the image. But as mentioned above, I did not manage to figure out which color space was used for saving the image, and even if I knew it, one would have to create an appropriate ColorSpace implementation. The first websearch results, like YCbCrColorSpace.java, did not work for the given input images...)

like image 21
Marco13 Avatar answered Nov 15 '22 15:11

Marco13