从CCRenderTexture获取像素的颜色

时间:2013-07-25 23:11:38

标签: iphone objective-c cocos2d-iphone

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

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

有没有办法改进以下代码以提高效率?

    // 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];

2 个答案:

答案 0 :(得分:1)

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

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

另请注意,一般来说,逐行遍历位图是个好主意,这意味着要反转for -loops的顺序(外部为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;

答案 1 :(得分:0)

每次都不要对你的缓冲区进行malloc,只需重用相同的缓冲区; malloc很慢!请看看Apple的Memory Usage Documentation

我不知道任何可以更快地执行此操作的算法,但这可能会有所帮助。