ImageIO 读数与其他方法的 RGB 值略有不同
我发现我在使用Java(实际上 paint.NET)时获得的RGB与使用ImageMagick,Gimp,Python和Octave时不同。最后4个都同意彼此,所以我假设是正确的。
对于这些示例,我使用以下测试映像:http://farm3.static.flickr.com/2811/9177301733_9836174725_o.jpg
测试像素x=4144 y=2768
R G B
Java = (125, 107, 69)
Paint.NET = (125, 107, 69)
ImageMagick = (128, 106, 67)
Python = (128, 106, 67)
Octave = (128, 106, 67)
Gimp = (128, 106, 67)
什么原因?
以下是使用 imagemagick 的快速测试:
convert image.jpg -crop 1x1+4144+2768 -depth 8 txt:
输出:
# ImageMagick pixel enumeration: 1,1,65535,srgb
0,0: (32896,27242,17219) #806A43 srgb(128,106,67)
以下是一些 Java 和 python 代码,它们也演示了这个问题:
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
public class ImageIOTest {
@Test
public void can_read_file() throws IOException, InterruptedException, URISyntaxException {
File tempFile = File.createTempFile("image", "jpg");
FileUtils.copyURLToFile(new URL("http://farm3.static.flickr.com/2811/9177301733_9836174725_o.jpg"), tempFile);
BufferedImage image = ImageIO.read(tempFile);
int javaRGB = image.getRGB(4144, 2768);
int javaRed = (javaRGB >> 16) & 0xFF;
int javaGreen = (javaRGB >> 8) & 0xFF;
int javaBlue = (javaRGB >> 0) & 0xFF;
System.out.printf("rgb: (%d, %d, %d)", javaRed, javaGreen, javaBlue);
}
}
下面是相应的 python 脚本:
from PIL import Image
import sys, urllib, cStringIO
file = cStringIO.StringIO(urllib.urlopen("http://farm3.static.flickr.com/2811/9177301733_9836174725_o.jpg").read())
im = Image.open(file)
pix = im.load()
print pix[4144, 2768]
我尝试过使用这个12monkeys库,希望这可以解决它,但没有骰子。任何其他想法如何使用java提取正确的RGB值?当然,我不是第一个遇到这个问题的人!
更新
我试过了,但得到相同的无效结果:输出:getRaster().getSample()
System.out.println(raster.getSample(4144, 2768, 0)+","+ raster.getSample(4144, 2768, 1)+","+ raster.getSample(4144, 2768, 2));
125,107,69
更多信息
下面是一些输出,显示图像左上角的前 9 个(3x3 平方)像素的三个不同工具解码的 RGB 值。正如你所看到的,Python和ImageMagick是一致的。Java有时会匹配。我已经在java不同意的地方放了一个X...:
Tool [x, y] = (R , G , B )
ImageIO : [0, 0] = (86, 90, 93)
Python : [0, 0] = (86, 90, 93)
ImageMagick : [0, 0] = (86, 90, 93)
ImageIO : [1, 0] = (86, 90, 93)
Python : [1, 0] = (86, 90, 93)
ImageMagick : [1, 0] = (86, 90, 93)
ImageIO : [2, 0] = (90, 91, 95) X
Python : [2, 0] = (88, 92, 95)
ImageMagick : [2, 0] = (88, 92, 95)
ImageIO : [0, 1] = (85, 93, 95)
Python : [0, 1] = (85, 93, 95)
ImageMagick : [0, 1] = (85, 93, 95)
ImageIO : [1, 1] = (85, 93, 95) X
Python : [1, 1] = (87, 92, 95)
ImageMagick : [1, 1] = (87, 92, 95)
ImageIO : [2, 1] = (87, 92, 95)
Python : [2, 1] = (87, 92, 95)
ImageMagick : [2, 1] = (87, 92, 95)
ImageIO : [0, 2] = (83, 93, 94)
Python : [0, 2] = (83, 93, 94)
ImageMagick : [0, 2] = (83, 93, 94)
ImageIO : [1, 2] = (83, 93, 94) X
Python : [1, 2] = (84, 92, 94)
ImageMagick : [1, 2] = (84, 92, 94)
ImageIO : [2, 2] = (83, 91, 93)
Python : [2, 2] = (83, 91, 93)
ImageMagick : [2, 2] = (83, 91, 93)
为什么Java为某些像素提供不同的值?或者,是否有另一种(快速)方法可以使用本机Java代码生成正确的值?
2016-09-26更新:
我提交了演示此问题的代码,并将其推送到github(imageio-test),以便我可以在不同的计算机上轻松测试它。事实证明,Java在OSX和Ubuntu Linux上都是一致的,但Python,ImageMagick和Octave是不一致的。换句话说,在Linux盒子上,所有工具都彼此一致,因此,我现在认为java一直都是正确的,而其他工具在OSX上给出了不正确的结果!我仍然不明白为什么,我也没有得到任何具体的证据来证明哪些值是正确的,但我正在得到一些东西......