Reputation: 10095
I'd like to implement a method which, given a CGRect within a UIView, returns the most used colour in that rect.
I've read answers to similar questions and I've gone through the Apple documentation to understand the code listed in those answers and the end result is a huge headache.
I'd appreciate it if someone could explain how to do this.
UPDATE
I've managed to create a working function by extending the colorAtPixel method demonstrated in rojkarc's link. I'm pretty sure this is not as efficient as it could. If anyone has suggestions for improving it, I'd be really grateful.
- (UIColor *) dominantColorInRect:(CGRect)rect
{
UIColor * dominantColor = nil;
NSMutableDictionary * dictionary = [[NSMutableDictionary alloc] init];
int bytesPerPixel = 4;
int bytesPerRow = bytesPerPixel * 1;
NSUInteger bitsPerComponent = 8;
unsigned char pixelData[4] = { 0, 0, 0, 0 };
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixelData, 1, 1, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
for (int x = rect.origin.x; x <= rect.size.width; x++) {
for (int y = 0; y <= rect.size.height; y++) {
context = CGBitmapContextCreate(pixelData, 1, 1, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
CGContextTranslateCTM(context, -x, -y);
[self.layer renderInContext:context];
CGContextRelease(context);
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) {
NSInteger count = [[dictionary objectForKey:color] integerValue];
count++;
[dictionary setObject:[NSNumber numberWithInt:count] forKey:color];
}
}
}
CGColorSpaceRelease(colorSpace);
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;
}
Upvotes: 3
Views: 841
Reputation: 2332
The following algorithm:
To create a color histogram, you have to get the colour of a pixel in a given location (like here:http://www.markj.net/iphone-uiimage-pixel-color/) And than you have to count (and collect) the frequency of a given color.
Create image:
if(UIGraphicsBeginImageContextWithOptions != NULL){
UIGraphicsBeginImageContextWithOptions(self.view.layer.frame.size, NO, 0.0);
}else {
UIGraphicsBeginImageContext(self.view.layer.frame.size);
}
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
img = UIGraphicsGetImageFromCurrentImageContext();
size_t imageSize = CGImageGetBytesPerRow(img.CGImage) * CGImageGetHeight(img.CGImage);
NSLog(@"imageSize: %zu",(imageSize/(1024*1024)));
UIGraphicsEndImageContext();
Create histogram: Google it, a lot of pseudocode/ objective-C code is available.
Upvotes: 2