与其他工具相比,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
:
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值也是正确的。谢谢!
正如你所提到的,这个问题与这个线程完全相同。您可以通过读取映像,然后将其写入文件来确认。它是这样的。
这个问题有多种解决方案。最简单的方法似乎是将twelve emonkeys的ImageIO jar作为依赖项包含到项目中。您不需要进行任何代码更改。
其他选择:
- Mark Jeronimus写了一个方法,将坏图像转换为正确的图像。我在你的样本图像上测试了一下,它有效。但是,您需要找到一种很好的方法来检测是否有必要进行转换。对这个答案有一个评论可能会有所帮助。根据ludovic的建议,您可以使用Toolkit的getImage来打开图像,而不是
ImageIO
,因为它没有相同的错误。