与其他工具相比,Java中从BufferedImage获得的RGB值不正确

本文关键字:RGB 不正确 BufferedImage 中从 工具 其他 Java | 更新日期: 2023-09-27 18:18:05

我正在尝试可靠地获得跨平台图像像素的RGB值。

对于我的测试,我使用别人提供给我的jpg图像(见编辑-情节变厚下面的部分)。

在c#中,我正在做类似于以下的事情(其中bmpData是一个BitmapData对象):

PixelData* pScan = (PixelData*)bmpData.Scan0;
...
struct PixelData
{
    internal byte r;
    internal byte g;
    internal byte b;
    internal PixelData(byte r, byte g, byte b)
    {
        this.r = r;
        this.g = g;
        this.b = b;
    }
}

在Java中,我尝试了以下图像是BufferedImage对象(从这个实用程序方法中读取的字节[]创建):http://docs.oracle.com/javase/7/docs/api/javax/imageio/ImageIO.html#read(java.io.InputStream)):

Raster raster = image.getRaster();
for(x){
   for(y){
      double[] pixel = raster.getPixel(x, y, new double[3]);

:

int rgb = image.getRGB(x, y);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;

:

Raster raster = image.getRaster();
int r = raster.getSample(x, y, 0);
int g = raster.getSample(x, y, 1);
int b = raster.getSample(x, y, 2);
对于我的测试图像,结果总是如下所示。例如,取第一个像素:

c#结果:


16 R =
60 G =
= 109

Java Result (in every case):
R = 52
< G/strong> = 160
= 102

我有三个问题:
1。为什么它们如此不同?
2。是因为我做错了吗?
3。在这两种情况下有更好的方法吗?

谢谢你提供的任何帮助!

编辑- 2015-10-19在有人建议我使用图像工具"挑选"第一个像素的颜色后,我照做了。取值如下:

Microsoft Paint:
R = 17
< G/strong> = 61
= 110

GIMP

:
16 R =
60 G =
= 109

所以我的问题变成了:
为什么RGB值从Java的buffereimage类如此错误?

编辑-情节变厚
我从GIMP导出图像,并通过相同的程序运行它,现在RGB数字都正确匹配。

GIMP导出过程中的某些东西已经改变了它,因此它现在在Java库中工作相同。

现在我需要弄清楚发生了什么变化!遗憾的是,我在这方面的知识有限。

我检查了alpha预计算,ColorModel和ColorSpace。一切都是一样的

图片(希望没有改变):
https://www.dropbox.com/s/9pc4nxwdav5s0za/correctRGBs.jpg?dl=0https://www.dropbox.com/s/fknlj1n4jcuk4pg/incorrectRGBs.jpg?dl=0


实现方案
在安德斯的建议下,我首先调查了十二个猴子的"插件",因为它似乎是最干净的解决方案。

我还注意到作者已经编写了一个插件来处理tiff文件,这是一个额外的好处,因为我以前通过它们的神奇数字识别tiff并使用JAI库进行转换。不需要了!

为了让它工作,我简单地添加了以下gradle依赖项:

compile 'com.twelvemonkeys.imageio:imageio-jpeg:3.1.2'
compile 'com.twelvemonkeys.imageio:imageio-tiff:3.1.2'

刷新并再次运行。当它再次运行时,我可以从调试器以及结果中看到图像已正确加载到BufferedImage对象中。

RGB值也是正确的。谢谢!

与其他工具相比,Java中从BufferedImage获得的RGB值不正确

正如你所提到的,这个问题与这个线程完全相同。您可以通过读取映像,然后将其写入文件来确认。它是这样的。

这个问题有多种解决方案。最简单的方法似乎是将twelve emonkeys的ImageIO jar作为依赖项包含到项目中。您不需要进行任何代码更改。

其他选择:

    Mark Jeronimus写了一个方法,将坏图像转换为正确的图像。我在你的样本图像上测试了一下,它有效。但是,您需要找到一种很好的方法来检测是否有必要进行转换。对这个答案有一个评论可能会有所帮助。根据ludovic的建议,您可以使用Toolkit的getImage来打开图像,而不是ImageIO,因为它没有相同的错误。