Я пытаюсь прочитать (среднее) RGB-значение центральных пикселей камеры iPhone.Это должно почти произойти в реальном времени.Поэтому я открываю UIImagePickerController, использую таймер, чтобы делать снимки каждые x секунд.Обработка изображения выполняется в отдельном потоке, чтобы он не блокировал приложение при вычислении значения RGB.Я попробовал несколько способов получить доступ к значениям RGB / pixel снятого изображения, но у всех есть проблема в том, что они слишком медленные и приводят к задержке обзора камеры.Я попробовал следующее:
- (UIColor *)getAverageColorOfImage:(UIImage*)image {
int pixelCount = kDetectorSize * kDetectorSize;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * kDetectorSize;
NSUInteger bitsPerComponent = 8;
unsigned char *rawData = malloc(pixelCount * bytesPerPixel);
CGContextRef context = CGBitmapContextCreate(rawData, kDetectorSize, kDetectorSize, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
NSLog(@"Drawing image");
CGContextDrawImage(context, CGRectMake(0, 0, kDetectorSize, kDetectorSize), [image CGImage]);
NSLog(@"Image drawn");
CGContextRelease(context);
// rawData contains the image data in the RGBA8888 pixel format. Alpha values are ignored
int byteIndex = 0;
CGFloat red = 0.0;
CGFloat green = 0.0;
CGFloat blue = 0.0;
for (int i = 0 ; i < pixelCount; ++i) {
red += rawData[byteIndex];
green += rawData[byteIndex + 1];
blue += rawData[byteIndex + 2];
byteIndex += bytesPerPixel;
}
free(rawData);
return [UIColor colorWithRed:red/pixelCount/255.0 green:green/pixelCount/255.0 blue:blue/pixelCount/255.0 alpha:1.0];
}
kDetectorSize установлен в 6 так, что обработанное изображение имеет размер 6x6 пикселей.Один из параметров изображения также был обрезан до 6x6 пикселей ранее.Медленная часть - это CGContextDrawImage, который занимает около 500-600 мс на моем iPhone 4. Я попробовал несколько альтернатив для этой строки:
UIGraphicsPushContext(context);
[image drawAtPoint:CGPointMake(0.0, 0.0)];
UIGraphicsPopContext();
или
UIGraphicsPushContext(context);
[image drawInRect:CGRectMake(0.0, 0.0, kDetectorSize, kDetectorSize)];
UIGraphicsPopContext();
Оба подхода медленнее, чемодин выше.Размер изображения не оказывает существенного влияния (я бы сказал, что это не имеет никакого влияния).Кто-нибудь знает более быстрый способ доступа к значению RGB?
Также было бы хорошо, если бы поток не вызывал задержку обзора камеры.Я так называю свою тему:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
[NSThread detachNewThreadSelector:@selector(pickColorFromImage:) toTarget:self withObject:image];
}
- (void)pickColorFromImage:(UIImage *)image {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[NSThread setThreadPriority:0.0];
[...cropping the image...]
UIColor *averageColor = [self getAverageColorOfImage:croppedImage];
[self performSelectorOnMainThread:@selector(applyPickedColor:) withObject:averageColor waitUntilDone:NO];
[pool release];
}
Спасибо за вашу помощь!