Saturday, August 17, 2013

How to check whether a UIImage is black and white or not?


Please do follow this post along with the post here

In one of my previous posts, I described on how I convert an image to black and white and grayscale as well. Here, I'm going to explain on how to check an image is black and white or not.

//checking whether the image is a black and white one or not
-(IBAction) checkBlackAndWhite:(id)sender
{
//sourceImage  is the user selected image from the Image Picker. I simply display it on a UIImageView and for the processing  i get the image that is currently viewed in the UIImageView
    BOOL blackNWhite=[self imageIsBlackAndWhite:sourceImage];
    
    if(sourceImage==nil)
    {
        NSLog(@"Image Not selected");
        
        alert=[[UIAlertView alloc] initWithTitle:@"Image Process" message:@"Image Not selected" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
        [alert show];
    }
    
    else
    {    
        if(blackNWhite==YES)
        {
            NSLog(@"Image is Black and White");
            
            alert=[[UIAlertView alloc] initWithTitle:@"Image Process" message:@"Image is Black and White" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
            [alert show];
        }
        
        else
        {
            NSLog(@"Image is not Black and White");
            
            alert=[[UIAlertView alloc] initWithTitle:@"Image Process" message:@"Image is not Black and White" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
            [alert show];
        }
    }
}

//method will check whther a selected image is a black and white image or not
-(BOOL)imageIsBlackAndWhite:(UIImage *)image
{
    BOOL isBlackNWhite=NO;

    // load image
    CGImageRef imageRef = image.CGImage;
    CFDataRef cfData = CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
    NSData * data = (__bridge NSData *) cfData;
    char *pixels = (char *)[data bytes];
    
    const int threshold = 10; //define a gray threshold
    
    for(int i = 0; i < [data length]; i += 4)
    {
        Byte red = pixels[i];
        Byte green = pixels[i+1];
        Byte blue = pixels[i+2];
        
        //check if a single channel is too far from the average value.
        //greys have RGB values very close to each other
        int average = (red+green+blue)/3;
        
        if( abs(average - red) >= threshold ||abs(average - green) >= threshold ||abs(average - blue) >= threshold )
        { 
            isBlackNWhite=NO;
        }
        
        else
        {
            isBlackNWhite=YES;
        }
    }
    CFRelease(cfData);
    return isBlackNWhite;
}