Java 读取图像时,源栅格波段数和源颜色空间分量不匹配
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23181306/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Numbers of source Raster bands and source color space components do not match when i read image
提问by Computernerd
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 questionand 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.
在研究中,有一个类似的问题,它似乎是我的 JPEG 图像的问题(它是从可能导致错误的更大图片中裁剪出来的),我必须解决灰度问题,但我不知道它是什么关于或如何实施它。
NOTE: At first i tried using ImageIcon to add to JPanel but it could not work hence i found this solutionwhich lead to my current problem. I just starting programming in Java.
注意:起初我尝试使用 ImageIcon 添加到 JPanel,但它无法工作,因此我找到了导致我当前问题的解决方案。我刚开始用 Java 编程。
EDIT: Here are the linkto the images and I am doing a Java Application
编辑:这是图像的链接,我正在做一个 Java 应用程序
I need an alternative to add a image to a JPanel.
我需要另一种方法将图像添加到 JPanel。
回答by Marco13
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 YPbPror YCbCrcolor space (I did not manage to figure out that one exactly, but they are both not supported in ImageIO by default).
然而,问题的原因是图像以某种奇怪的YPbPr或YCbCr颜色空间形式存储(我没有设法确切地找出那个,但默认情况下 ImageIO 不支持它们)。
Neither of my attempts to apply the standard color conversionsfor YPbPb->RGB or YCbCb->RGB seemed to reproduce the exactoriginal 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....
我尝试为 YPbPb->RGB 或 YCbCb->RGB应用标准颜色转换的尝试都没有重现准确的原始颜色,但正如您在浏览维基百科文章时可能注意到的那样:世界上释放了相当多的学术蒸汽色彩空间....
Again: I'd stronglyrecommend 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.
再次:我强烈建议您使用任何图像查看器/编辑器打开图像,并将它们保存为“标准”格式。最好是 PNG,因为 JPG 并不真正适合这些类型的图像。JPG 更适用于“自然”图像,例如照片。对于此类“人造”图像,压缩率必须非常低以避免伪影。
However, this program shows the image with nearlycorrect 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 whichcolor 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...)
(注意:这可以更简单地实现ColorConvertOp
,将用于图像的颜色空间转换为 RGB 颜色空间。但如上所述,我没有设法弄清楚哪个颜色空间用于保存图像,即使我知道,也必须创建一个适当的ColorSpace
实现。第一个网络搜索结果,如YCbCrColorSpace.java,对给定的输入图像不起作用......)
回答by Sinisha Mihajlovski
This question has already been answered here: https://stackoverflow.com/a/18400559/1042999and 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
这个问题已经在这里得到了回答:https: //stackoverflow.com/a/18400559/1042999,这是一个非常优雅的问题解决方案。该解决方案涉及使用 ImageIO 插件,实现对默认 ImageIo 实现不支持的多种格式的支持。有关如何在常规 Java 应用程序和 servlet 容器中使用该插件的详细信息,请参见:https: //github.com/haraldk/TwelveMonkeys