当我读取图像时,源光栅波段和源色彩空间分量的数量不匹配[重复]

Posted

技术标签:

【中文标题】当我读取图像时,源光栅波段和源色彩空间分量的数量不匹配[重复]【英文标题】:Numbers of source Raster bands and source color space components do not match when i read image [duplicate] 【发布时间】:2014-06-04 13:37:48 【问题描述】:

当我尝试使用以下代码读取图像时

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应用程序

我需要一个替代方法来将图像添加到 JPanel。

【问题讨论】:

您能否提供您尝试加载的确切 JPG 文件?是否可以在这里使用“简单”的特定解决方法,例如使用任何图像查看器程序加载图像,然后再次保存(然后,可能以可以毫无问题地读取的格式)? 【参考方案1】:

这里已经回答了这个问题:https://***.com/a/18400559/1042999,这是一个非常优雅的问题解决方案。该解决方案涉及使用 ImageIO 插件,实现了对默认 ImageIo 实现不支持的多种格式的支持。有关如何在常规 java 应用程序和 servlet 容器中使用该插件的详细信息,可以找到:https://github.com/haraldk/TwelveMonkeys

【讨论】:

Maven 依赖:<dependency><groupId>com.twelvemonkeys.imageio</groupId><artifactId>imageio-jpeg</artifactId><version>3.3.1</version></dependency>【参考方案2】:

使用任何图像查看器/编辑器打开图像,并将它们保存为“标准”格式

我想知道这些图像最初是如何创建的。我的猜测是您使用了一些花哨、复杂的图像处理程序来进行您提到的“裁剪”,并且该程序允许以某些不寻常的格式存储图像,并且您已经(或没有)修改了一些具有保存图像时可用,不知道这些选项的确切含义(如果我低估了您对图像格式和色彩空间的熟悉程度,请见谅...)。

但是,问题的原因是图像以某种奇怪的YPbPr 或YCbCr 色彩空间形式存储(我没有设法准确地找出一个,但它们都不支持默认情况下为 ImageIO)。

我尝试为 YPbPb->RGB 或 YCbCb->RGB 应用标准 color conversions 似乎都没有重现 精确 原始颜色,但您在浏览 Wikipedia 文章时可能会注意到: 在色彩空间的世界里,相当多的学术蒸汽被释放了....

再次重申:我强烈建议您使用任何图像查看器/编辑器打开图像,并将它们保存为“标准”格式。最好是 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, 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;
    

(注意:这可以更简单地实现,使用 ColorConvertOp 从用于图像的颜色空间转换为 RGB 颜色空间。但如上所述,我没有设法弄清楚 哪个颜色空间用于保存图像,即使我知道,也必须创建适当的ColorSpace 实现。第一个网络搜索结果,如YCbCrColorSpace.java,不适用于给定的输入图像...)

【讨论】:

MS Paint 似乎吐出了有这个问题的文件,至少对我来说是这样。有什么好的免费应用程序或(甚至更好的)网站可以解决这个问题? @ArtOfWarfare 我不知道(也几乎没想到)MS Paint 可以创建这样的文件。 (在这里吞下关于“微软和标准”的咆哮)。关于应用程序:基本上任何程序都应该能够创建“正确”的 PNG 文件,我对 irfanview.com 很满意,但你可以选择你喜欢的,或者(如果你不关心潜在的隐私/版权问题), 任何类似“在线png转换器”的网络搜索结果... 我特别需要将文件保留为 jpeg - 这是客户的要求(我同意 png 在各方面都会更好,但他们会写支票,所以我照他们说的做)。无论如何,我找到了一个解决方案 - 我在 gimp 中打开文件,然后使用所有默认设置导出为 jpeg。

以上是关于当我读取图像时,源光栅波段和源色彩空间分量的数量不匹配[重复]的主要内容,如果未能解决你的问题,请参考以下文章

PIE SDK彩色空间变换

彩色图像色彩空间原理

图像色彩空间转换

如何在OpenCV中使用Adobe RGB色彩空间读取jpeg图像?

使用 Polygon 裁剪光栅文件并使用相同的文件名写入输出

Rasterio源形状与给定索引1不一致