当我尝试使用以下代码阅读图像
myPicture = ImageIO.read(new File("./src/javaassignment1b/Deck/Ace_Diamond_1.jpg"));
我收到以下错误
Numbers of source Raster bands and source color space components do not match
在研究中,有一个类似的question,它似乎是我的JPEG图像的一个问题(它是从更大的图片裁剪可能导致错误),我必须解决灰度问题,我不知道是什么关于或如何实现它.
注意:起初我试图使用ImageIcon添加到JPanel,但它无法工作,因此我发现这个solution导致我目前的问题.我刚开始用Java编程.
编辑:这里是link的图像,我正在做一个Java应用程序
解决方法
我不知道图像是如何创建的.我的猜测是,您已经使用了一些您所提到的“裁剪”的花哨,复杂的图像处理程序,并且该程序允许以一些不寻常的格式存储图像,并且您(或没有)修改一些在保存图像时可以使用,不知道这些选项是什么意思(如果我低估了对这里的图像格式和颜色空间的熟悉程度,则表示歉意).
然而,问题的原因是图像以YPbPr或YCbCr颜色空间的一些奇怪形式存储(我没有设法弄清楚那个,但默认情况下它们都不支持ImageIO).
我对于YPbPb-> RGB或YCbCb-> RGB的标准color conversions的尝试都没有尝试再现准确的原始颜色,但是您可能会注意到,在阅读维基百科的文章时:相当一些学术蒸气在彩色空间世界….
再次强烈建议您使用任何图像查看器/编辑器打开图像,并将其保存为“标准”格式.最好是作为PNG,因为JPG并不适合这些图像. JPG更适用于“自然”图像,如照片.对于这样的“人造”图像,压缩必须非常低以避免伪像.
然而,该程序显示的图像具有几乎正确的颜色,但颜色转换似乎还不完全正确.
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,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,G)); B = Math.min(1.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; } }
(注意:这可以实现得更简单,ColorConvertOp可以从用于图像的颜色空间转换为RGB颜色空间,但是如上所述,我没有想出可以使用哪个颜色空间来保存图像,即使我知道,也必须创建一个适当的ColorSpace实现.第一个websearch结果,如YCbCrColorSpace.java,不适用于给定的输入图像…)