C#屏幕像素颜色检索报错:Parameter must be positive and < Height. (Parameter 'y')
解决System.ArgumentOutOfRangeException:y参数超出范围的问题
嘿,这个问题其实是个很容易犯的笔误,我帮你揪出来了!
核心错误:循环条件写错了
看你内层的y循环:
for (int y = 0; x < SystemInformation.VirtualScreen.Height; y++)
这里的循环判断条件用了x < ...而不是y < ...!这就导致y会一直无限递增,直到超过你创建的Bitmap的高度,调用GetPixel(x,y)时自然就抛出ArgumentOutOfRangeException了。
额外需要修正的几个问题
除了这个笔误,还有几个潜在问题会导致后续麻烦:
- 资源未释放:Bitmap和Graphics都是非托管资源,不用using包裹的话会造成内存泄漏
- 循环范围不匹配:你创建的Bitmap是主屏幕的大小,但循环遍历的是虚拟屏幕(多显示器场景下会更大),同样会导致x/y超出Bitmap范围
- UI更新的小问题:字符串转义错误(
<要改成<,"改成"),还有label更新可以优化下避免频繁刷新
修正后的完整代码
private bool SearchPixel(string hexcode) { try { // 获取屏幕范围,这里统一用虚拟屏幕(支持多显示器) var screenBounds = SystemInformation.VirtualScreen; // 使用using自动释放资源 using (Bitmap bitmap = new Bitmap(screenBounds.Width, screenBounds.Height)) using (Graphics graphics = Graphics.FromImage(bitmap)) { graphics.CopyFromScreen(screenBounds.X, screenBounds.Y, 0, 0, screenBounds.Size); Color desiredPixelColor = ColorTranslator.FromHtml(hexcode); // 循环范围和Bitmap大小保持一致 for (int x = 0; x < screenBounds.Width; x++) { for (int y = 0; y < screenBounds.Height; y++) // 这里把x改成y! { Color currentPixelColor = bitmap.GetPixel(x, y); label1.Text = $"Current colour: {currentPixelColor}"; if (desiredPixelColor == currentPixelColor) { label2.Text = "You are on the colour!"; return true; } } } label2.Text = "You are not on the colour!"; return false; } } catch (Exception ex) { // 可以在这里加日志,方便排查其他问题 label2.Text = $"Error: {ex.Message}"; return false; } } private void timer1_Tick(object sender, EventArgs e) { SearchPixel("#hexcolourgoeshere"); }
为什么之前label1能更新?
因为在y值还没超出Bitmap高度的时候,循环已经执行了几次,所以label1能显示颜色,但当y超过Bitmap.Height后,就抛出异常被catch捕获,返回false,所以你会看到定时器每秒都报错。
内容的提问来源于stack exchange,提问作者user19232186
相关产品推荐
相关产品推荐

