Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply Black and White Filter to UIImage

Tags:

I need to apply a black-and-white filter on a UIImage. I have a view in which there's a photo taken by the user, but I don't have any ideas on transforming the colors of the image.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.title = NSLocalizedString(@"#Paint!", nil);
    imageView.image = image;
}

How can I do that?

like image 788
user3422862 Avatar asked Mar 15 '14 10:03

user3422862


People also ask

How do I make a picture black and white in Swift?

If you use gray as your tint color, it produces plain black and white images, but you can also use other colors to get sepia tone and other effects. To make that work you'll need a UIImage called yourUIImage , then replace the print(processedImage.

What is Ciimage in Swift?

A representation of an image to be processed or produced by Core Image filters.


2 Answers

Objective C

- (UIImage *)convertImageToGrayScale:(UIImage *)image {


    // Create image rectangle with current image width/height
    CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);

    // Grayscale color space
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

    // Create bitmap content with current image size and grayscale colorspace
    CGContextRef context = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, 0, colorSpace, kCGImageAlphaNone);

    // Draw image into current context, with specified rectangle
    // using previously defined context (with grayscale colorspace)
    CGContextDrawImage(context, imageRect, [image CGImage]);

    // Create bitmap image info from pixel data in current context
    CGImageRef imageRef = CGBitmapContextCreateImage(context);

    // Create a new UIImage object
    UIImage *newImage = [UIImage imageWithCGImage:imageRef];

    // Release colorspace, context and bitmap information
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    CFRelease(imageRef);

    // Return the new grayscale image
    return newImage; 
}

Swift

func convertToGrayScale(image: UIImage) -> UIImage {

    // Create image rectangle with current image width/height
    let imageRect:CGRect = CGRect(x:0, y:0, width:image.size.width, height: image.size.height)

    // Grayscale color space
    let colorSpace = CGColorSpaceCreateDeviceGray()
    let width = image.size.width
    let height = image.size.height

    // Create bitmap content with current image size and grayscale colorspace
    let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue)

    // Draw image into current context, with specified rectangle
    // using previously defined context (with grayscale colorspace)
    let context = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
    context?.draw(image.cgImage!, in: imageRect)
    let imageRef = context!.makeImage()

    // Create a new UIImage object
    let newImage = UIImage(cgImage: imageRef!)

    return newImage
}
like image 71
MCMatan Avatar answered Sep 18 '22 14:09

MCMatan


Judging by the ciimage tag, perhaps the OP was thinking (correctly) that Core Image would provide a quick and easy way to do this?

Here's that, both in ObjC:

- (UIImage *)grayscaleImage:(UIImage *)image {
    CIImage *ciImage = [[CIImage alloc] initWithImage:image];
    CIImage *grayscale = [ciImage imageByApplyingFilter:@"CIColorControls"
        withInputParameters: @{kCIInputSaturationKey : @0.0}];
    return [UIImage imageWithCIImage:grayscale];
}

and Swift:

func grayscaleImage(image: UIImage) -> UIImage {
    let ciImage = CIImage(image: image)
    let grayscale = ciImage.imageByApplyingFilter("CIColorControls",
        withInputParameters: [ kCIInputSaturationKey: 0.0 ])
    return UIImage(CIImage: grayscale)
}

CIColorControls is just one of several built-in Core Image filters that can convert an image to grayscale. CIPhotoEffectMono, CIPhotoEffectNoir, and CIPhotoEffectTonal are different tone-mapping presets (each takes no parameters), and you can do your own tone mapping with filters like CIColorMap.

Unlike alternatives that involve creating and drawing into one's own CGBitmapContext, these preserve the size/scale and alpha of the original image without extra work.

like image 30
rickster Avatar answered Sep 18 '22 14:09

rickster