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.
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
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...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With