在CGRect中找不到主色的算法不起作用

时间:2014-01-24 18:21:13

标签: ios objective-c core-graphics

我正在尝试编写一个方法,在UIView中返回区域内最常用的颜色(由CGRect表示)。

这是我迄今为止开发的代码,但它似乎不起作用。 NSLog输出列出了每个像素的颜色,即使我添加了一些红色条纹,它也总是显示白色(255,255,255)。

如果有人能告诉我问题在哪里,我会很感激:

- (UIColor *) dominantColorInRect:(CGRect)rect
{
    UIColor * dominantColor = nil;
    NSMutableDictionary * dictionary = [[NSMutableDictionary alloc] init];

    int bytesPerPixel = 4;
    int bytesPerRow = bytesPerPixel * rect.size.width;
    NSUInteger bitsPerComponent = 8;
    unsigned int bitmapSize = bytesPerRow * rect.size.height;
    unsigned char pixelData[bitmapSize];

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = CGBitmapContextCreate(pixelData,
                                                 rect.size.width,
                                                 rect.size.height,
                                                 bitsPerComponent,
                                                 bytesPerRow,
                                                 colorSpace,   
                                                 kCGImageAlphaPremultipliedLast);


    CGContextTranslateCTM(context, -rect.origin.x, -rect.origin.y);
    [self.layer renderInContext:context];

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    if (pixelData) {
        unsigned long size = sizeof(pixelData)/sizeof(unsigned char);
        for (int i = 0; i < size; i += bytesPerPixel) {
            UIColor * color = [UIColor colorWithRed:pixelData[0]/255.0 
                                       green:pixelData[1]/255.0 
                                       blue:pixelData[2]/255.0 
                                       alpha:pixelData[3]/255.0];

            if (color) {

                const CGFloat * colors = CGColorGetComponents( color.CGColor);
                CGFloat red = colors[0]*255;
                CGFloat green = colors[1]*255;
                CGFloat blue = colors[2]*255;

                NSLog(@"This Color: %f,%f,%f",red,green,blue);


                NSInteger count = [[dictionary objectForKey:color] integerValue];
                count++;
                [dictionary setObject:[NSNumber numberWithInt:count] forKey:color];
            }

        }

    }

    int highestFrequency = 0;
    for (id color in dictionary) {
        NSInteger count = [[dictionary objectForKey:color] integerValue];
        //NSInteger count = [object[1] integerValue];
        if (count > highestFrequency) {
            highestFrequency = count;
            dominantColor = color;
        }
    }

    return dominantColor;
}

2 个答案:

答案 0 :(得分:4)

您重复读取

中第一个像素的值
UIColor * color = [UIColor colorWithRed:pixelData[0]/255.0 
                                   green:pixelData[1]/255.0 
                                   blue:pixelData[2]/255.0 
                                   alpha:pixelData[3]/255.0];

我认为应该像

UIColor * color = [UIColor colorWithRed:pixelData[i]/255.0 
                                   green:pixelData[i+1]/255.0 
                                   blue:pixelData[i+2]/255.0 
                                   alpha:pixelData[i+3]/255.0];

答案 1 :(得分:1)

您正在使用kCGImageAlphaPremultipliedLast,它将返回每个组件的整数值(可能在0-255范围内)。

然后将这些值转换为浮点,创建一个UIColor,询问该颜色的R / G / B值,然后将值转换回0-255范围内的整数。为什么要经历这一切?只询问像素数据的字节值。

然后使用UIColor对象作为字典中的键。除了原色之外,这种方法很快就会崩溃。一个RGBA  颜色有2 ^ 32个可能的值,或4个可能的值。对于照片,您可能会为图像中的每个像素获得不同的颜色值,并且在尝试创建包含数百万个条目的字典时会耗尽内存。

我不知道为什么你没有记录任何白色像素,但你的设计存在缺陷,你应该重新开始。