【问题标题】:BufferedImage & createScreenCapture produces wrong colorsBufferedImage & createScreenCapture 产生错误的颜色
【发布时间】:2011-06-29 10:55:49
【问题描述】:

在我的 Java 程序中,我需要分析给定坐标中像素的颜色。因为我需要经常做,所以我先截取屏幕的一部分,然后得到一个像素颜色。我正在这样做:

BufferedImage bi = robot.createScreenCapture(new Rectangle(0,0,100,100));
...
pxcolor = GetPixelColor(bi,x,y);
...
ImageIO.write(bi, "bmp", new File("myScreenShot.bmp"));

GetPixelColor 函数很明显:

public Color GetPixelColor(BufferedImage b, int x, int y)
{
    int pc = b.getRGB(x, y);
    Color ccc = new Color(pc,true);
    int  red = (pc & 0x00ff0000) >> 16;   // for testing
    int  green = (pc & 0x0000ff00) >> 8;  // for testing
    int  blue = pc & 0x000000ff;          // for testing
    return ccc;     
}

出于测试目的,我创建了一个pure pink picture (RGB(255,0,255))。问题是 即使像素是纯粉红色,该函数也会返回 RGB(250,61,223) 之类的内容,并在那里测试红色、绿色和蓝色变量。另外,保存的文件(myScreenShot.bmp)looks quite different

我做错了什么。会不会与 ColorModel 相关?

UPD:从 bi 获取 DataBuffer 似乎不会产生正确的结果 - 生成的 DataBuffer 的第一个元素等于“-2105371”。我不知道减号是从哪里来的,但是如果我将其转换为十六进制,我会得到类似“FFFFFFFFFFDFDFE5”的东西。真正的像素 RGB 是 (E5,E5,EB),缓冲区已经损坏,取而代之的是 RGB(DF,DF,E5)。这已经让我发疯了。

【问题讨论】:

  • @Quest: getRGB 不仅速度惊人(最多 3 个订单,是的...慢了 1000 倍!!!,在 MacMini 上反复测量OS X 10.5)但它也是“错误的”,因为它试图对颜色模型“聪明”。我真的建议您使用由 int[] 支持的 BufferedImage 并直接从 int[] 操作像素,而不是使用 getRGB / setRGB .然后,您将读取使用 Robot 的 createScreenCapture 捕获的确切像素,并且您将 快速 读取它们。去过那里,做到了。
  • @Quest:除此之外,如果您打算解析大量捕获的像素(例如,检查 1920x1200 屏幕的每个像素),那么您将不得不处理拥有数百万像素,您会发现整个“对象”概念根本无法快速削减它。 Color 对于非常简单的东西来说实际上是一个非常蹩脚的对象抽象:一个快速、精简、优雅的原始 int(通常表示像素的 ARGB 值,每个 8 位)。
  • @SyntaxT3rr0r。正如我在更新部分所写的,“缓冲区”似乎已经有错误的值,所以如果我从中取出第一个字节,它就已经不正确了。好的,不是第一个字节,因为它是 alpha,而是第二个。请给我一些代码示例,因为可能我提取的缓冲区不正确。
  • @Quest: 如果 src 是一个 BufferedImage 由 int[] 支持(实验/Google),那么 int[] srcbuf = ((DataBufferInt) src.getRaster().getDataBuffer()).getData(); 会给你和int[]。然后很简单:srcbuf[0] = 0xFFFF00FF 将在像素 (0,0) 处放置一个“纯粉色”(如您所说)。然后 int p = srcbuf[0] 会给你你的纯粉红色像素。另外,请投票并收藏以下问题(它包含您所追求的示例):stackoverflow.com/questions/2825837
  • 它似乎没有 int 支持,即使我不确定你的意思,但是 int[] srcbuf = ((DataBufferInt) src.getRaster().getDataBuffer()).getData ();产生一个错误,指出 DataBuffer 无法转换为 DataBufferInt。如果我在调用 createScreenCapture 的行进行调试并停止,在“变量”窗口中,我可以看到缓冲区已经有一些错误的值。此外,在我的 Windows 机器上一切正常,在我的 Mac 上 - 颜色错误。

标签: java bufferedimage


【解决方案1】:

这很可能是由于颜色模型。

根据this code,它使用DirectColorModel(见下文),无论您的屏幕颜色深度如何。

/*
 * Fix for 4285201
 * Create a DirectColorModel equivalent to the default RGB ColorModel,
 * except with no Alpha component.
 */
screenCapCM = new DirectColorModel(24,
                 /* red mask */    0x00FF0000,
                 /* green mask */  0x0000FF00,
                 /* blue mask */   0x000000FF);

【讨论】:

  • 我刚刚尝试使用反射更改颜色模型,但不幸的是,问题看起来更严重; RobotPeer.getRGBPixels 返回不正确的 RGB 值。所以看来这个问题与使用中的ColorModel 无关。
猜你喜欢
  • 2012-01-26
  • 1970-01-01
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-02
  • 1970-01-01
  • 2012-02-26
相关资源
最近更新 更多