获取BufferedImage
的每个像素的RGB值的最快方法是什么?
现在我正在使用两个for
循环获取RGB值,如下面的代码所示,但由于嵌套循环运行总共479999次,因此获取这些值花费的时间太长。如果我使用16位图像,这个数字会更高!
我需要一种更快的方法来获取像素值。
以下是我目前正在尝试使用的代码:
BufferedImage bi=ImageIO.read(new File("C:\\images\\Sunset.jpg"));
int countloop=0;
for (int x = 0; x <bi.getWidth(); x++) {
for (int y = 0; y < bi.getHeight(); y++) {
Color c = new Color(bi.getRGB(x, y));
System.out.println("red=="+c.getRed()+" green=="+c.getGreen()+" blue=="+c.getBlue()+" countloop="+countloop++);
}
}
答案 0 :(得分:12)
我不知道这是否有用,我还没有测试过,但你可以这样得到rgb值:
BufferedImage bi=ImageIO.read(new File("C:\\images\\Sunset.jpg"));
int[] pixel;
for (int y = 0; y < bi.getHeight(); y++) {
for (int x = 0; x < bi.getWidth(); x++) {
pixel = bi.getRaster().getPixel(x, y, new int[3]);
System.out.println(pixel[0] + " - " + pixel[1] + " - " + pixel[2] + " - " + (bi.getWidth() * y + x));
}
}
如您所见,您不必在循环内初始化新的Color。我也按照onemasse的建议反转了宽度/高度循环,以便从我已有的数据中检索计数器。
答案 1 :(得分:5)
通过从一堆单独的getRGB更改为一个大的getRGB来将整个图像复制到一个数组中,执行时间从一个数量级下降了33,000毫秒到3,200毫秒,而时间创建了数组只有31毫秒。 德尔>
毫无疑问,对数组进行了大量读取并对数组进行直接索引比许多单独读取要快得多。 德尔>
性能差异似乎与在类末尾使用断点语句有关。当断点位于循环之外时,类中的每一行代码似乎都会针对断点进行测试。改为个人获取不会提高速度。
由于代码仍然正确,答案的其余部分可能仍然有用。
旧阅读声明
colorRed=new Color(bi.getRGB(x,y)).getRed();
读取语句将位图复制到数组中
int[] rgbData = bi.getRGB(0,0, bi.getWidth(), bi.getHeight(),
null, 0,bi.getWidth());
将getRGB放入数组会将所有3个颜色值放入单个数组元素中,因此必须通过旋转和“和”来提取单个颜色。 y坐标必须乘以图像的宽度。
从数组中读取单个颜色的代码
colorRed=(rgbData[(y*bi.getWidth())+x] >> 16) & 0xFF;
colorGreen=(rgbData[(y*bi.getWidth())+x] >> 8) & 0xFF;
colorBlue=(rgbData[(y*bi.getWidth())+x]) & 0xFF;
答案 2 :(得分:2)
您是否尝试过BufferedImage.getRGB(int, int ,int ,int, int[] , int , int)?
类似的东西:
int[] rgb = bi.getRGB(0,0, bi.getWidth(), bi.getHeight(), new int[bi.getWidth() * bi.getHeight(), bi.getWidth()])
没试过,所以不确定它是否更快。
修改强> 看了@代码,它可能不是,但值得一试。
答案 3 :(得分:2)
您应该循环外循环中的行和内部的列。这样你就可以避免缓存未命中。
答案 4 :(得分:0)
我在这里找到了解决方案 https://alvinalexander.com/blog/post/java/getting-rgb-values-for-each-pixel-in-image-using-java-bufferedi
BufferedImage bi = ImageIO.read(new File("C:\\images\\Sunset.jpg"));
for (int x = 0; x < bi.getWidth(); x++) {
for (int y = 0; y < bi.getHeight(); y++) {
int pixel = bi.getRGB(x, y);
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel) & 0xff;
System.out.println("red: " + red + ", green: " + green + ", blue: " + blue);
}
}