需要更快的方法来获取缓冲图像的每个像素的RGB值
image-processing
java
6
0

获取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++);                                                                                                                                                  
    }
}
参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

我不知道这是否有帮助,我还没有测试过,但是您可以通过以下方式获取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));
    }
}

如您所见,您不必在循环内初始化新的颜色。我还按照onemasse的建议反转了宽度/高度循环,以从我已有的数据中检索计数器。

收藏
评论

您应该在外循环中循环行,在内循环中循环行。这样,您将避免缓存未命中。

收藏
评论

您是否尝试过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()])

没有尝试,所以不确定是否更快。

编辑看完@代码后,它可能不是,但是值得一试。

收藏
评论

通过将一堆单独的getRGB更改为一个大的getRGB,以将整个图像复制到一个数组中,执行时间从33,000毫秒减少到3200毫秒,减少了一个数量级,而创建数组的时间仅为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; 
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号