图像编辑模糊选择工具出现ArrayIndexOutOfBoundsException问题求助
问题分析与修复
核心错误原因
- 错误使用按位与
&而非短路与&&:你的条件判断里用了&,这是按位与操作,不会触发短路逻辑——哪怕x>0不成立(比如x=0),后面的grid[x-1][y]依然会被执行,直接导致索引-1的数组越界异常。 - 循环变量被意外篡改:在添加队列元素时,你用了
--x、++x这类操作修改当前循环的x/y变量,导致后续的条件判断使用的是已经改变后的值,会引发逻辑混乱(比如处理完左邻域后,x已经变小,再处理右邻域时就会基于错误的坐标)。
修复后的完整代码
package tests; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.ArrayDeque; import javax.swing.JFrame; import javax.swing.JPanel; public class FuzzySelectTest { public static void main(String[] args) { BufferedImage img = new BufferedImage(1920, 1080, BufferedImage.TYPE_INT_ARGB); boolean grid[][] = new boolean[img.getWidth()][img.getHeight()]; int x = 500, y = 500; JFrame frame = new JFrame(); JPanel panel = new JPanel(){ @Override public void paintComponent(Graphics g){ g.drawImage(img, 0, 0, null); } }; if(!(x < 0 || y < 0 || x >= img.getWidth() || y >= img.getHeight())){ ArrayDeque<int[]> queue = new ArrayDeque<>(); queue.add(new int[] {x, y}); final int imageWidth = img.getWidth(), imageHeight = img.getHeight(), originalColor = img.getRGB(x, y); grid[x][y] = true; while(!queue.isEmpty()){ int[] p = queue.poll(); x = p[0]; y = p[1]; System.out.println(x + " " + y + " " + grid[x][y]); // 替换&为短路与&&,直接使用x-1而非修改原变量 if(x > 0 && !grid[x - 1][y] && img.getRGB(x - 1, y) == originalColor){ queue.add(new int[] {x - 1, y}); grid[x - 1][y] = true; } if(y > 0 && !grid[x][y - 1] && img.getRGB(x, y - 1) == originalColor){ queue.add(new int[] {x, y - 1}); grid[x][y - 1] = true; } if(x + 1 < imageWidth && !grid[x + 1][y] && img.getRGB(x + 1, y) == originalColor){ queue.add(new int[] {x + 1, y}); grid[x + 1][y] = true; } if(y + 1 < imageHeight && !grid[x][y + 1] && img.getRGB(x, y + 1) == originalColor){ queue.add(new int[] {x, y + 1}); grid[x][y + 1] = true; } } } for(int yy = 0 ; yy < grid[0].length ; yy++){ for(int xx = 0 ; xx < grid.length ; xx++){ if(grid[xx][yy]) img.setRGB(xx, yy, Color.white.getRGB()); else img.setRGB(xx, yy, Color.black.getRGB()); } } frame.add(panel); frame.setSize(1920, 1080); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
关键修复点说明
- 逻辑运算符替换:把所有
&改成&&,利用短路求值特性——当第一个条件不满足时,后续的数组访问操作会被直接跳过,彻底避免索引越界。 - 保留原始坐标变量:不再修改循环中的
x和y,直接计算邻域坐标(比如x-1、y+1)并传入队列,同时直接标记对应grid位置为true,确保每个条件判断都基于当前节点的原始坐标,逻辑更可靠。
内容的提问来源于stack exchange,提问作者The Dog on the Log
相关产品推荐
相关产品推荐

