0

所以,我试图找到屏幕上任何特定颜色的像素的位置。

以下代码有效,但非常慢,因为我必须遍历每个像素坐标,而且有很多。

有什么方法可以改进以下代码以提高效率吗?

    // Detect the position of all red points in the sprite
    UInt8 data[4];

    CCRenderTexture* renderTexture = [[CCRenderTexture alloc] initWithWidth: mySprite.boundingBox.size.width * CC_CONTENT_SCALE_FACTOR()
                                                                     height: mySprite.boundingBox.size.height * CC_CONTENT_SCALE_FACTOR()
                                                                pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
    [renderTexture begin];
    [mySprite draw];

    for (int x = 0; x < 960; x++)
    {
        for (int y = 0; y < 640; y++)
        {                
            ccColor4B *buffer = malloc(sizeof(ccColor4B));
            glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
            ccColor4B color = buffer[0];

            if (color.r == 133 && color.g == 215 && color.b == 44)
            {
                NSLog(@"Found the red point at x: %d y: %d", x, y);
            }
        }
    }

    [renderTexture end];
    [renderTexture release];
4

2 回答 2

1

您可以(并且应该)一次读取多个像素。使 OpenGL 快速运行的方法是将所有内容打包到尽可能少的操作中。这适用于两种方式(读取和写入 GPU)。

尝试一次调用读取整个纹理,并从结果数组中找到您的红色像素。如下。

另请注意,一般来说,逐行遍历位图是个好主意,这意味着颠倒 for 循环的顺序(y [rows] 在外面, x 在里面)

// Detect the position of all red points in the sprite
ccColor4B *buffer = new ccColor4B[ 960 * 640 ];

CCRenderTexture* renderTexture = [[CCRenderTexture alloc] initWithWidth: mySprite.boundingBox.size.width * CC_CONTENT_SCALE_FACTOR()
                                                                 height: mySprite.boundingBox.size.height * CC_CONTENT_SCALE_FACTOR()
                                                            pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
[renderTexture begin];
[mySprite draw];

glReadPixels(0, 0, 940, 640, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

[renderTexture end];
[renderTexture release];

int i = 0;
for (int y = 0; y < 640; y++)
{
    for (int x = 0; x < 960; x++)
    {                            
        ccColor4B color = buffer[i];//the index is equal to y * 940 + x
        ++i;
        if (color.r == 133 && color.g == 215 && color.b == 44)
        {
            NSLog(@"Found the red point at x: %d y: %d", x, y);
        }
    }
}
delete[] buffer;
于 2014-11-25T06:22:57.783 回答
0

不要每次都 malloc 缓冲区,只需重用相同的缓冲区;malloc 很慢!请查看 Apple 的内存使用文档

我不知道有什么算法可以更快地做到这一点,但这可能会有所帮助。

于 2013-07-25T23:22:56.533 回答