Convert an Image (UIImage) to Grayscale

A trick you won’t need often, yet when the day arrives, you’ll have this up your sleeve – a quick method to convert a UIImage object to grayscale.

- (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;
}

Simple enough – here is an example of a converted image:

  1. Fantastic! Short and sweet solutions to stuff I’ve been looking for for ages are all over your blog! Thank you!

  2. Is there any way to preserve the background transparency of an image? I’ve tried playing around with kCGImageAlpha but no luck.

  3. A little addition to allow it to handle alpha transparency from the original image and to preserve image scale and orientation from the original image (especially for retina displays):

    – (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]);

    /* changes start here */
    // Create bitmap image info from pixel data in current context
    CGImageRef grayImage = CGBitmapContextCreateImage(context);

    // release the colorspace and graphics context
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);

    // make a new alpha-only graphics context
    context = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, 0, nil, kCGImageAlphaOnly);

    // draw image into context with no colorspace
    CGContextDrawImage(context, imageRect, [image CGImage]);

    // create alpha bitmap mask from current context
    CGImageRef mask = CGBitmapContextCreateImage(context);

    // release graphics context
    CGContextRelease(context);

    // make UIImage from grayscale image with alpha mask
    UIImage *grayScaleImage = [UIImage imageWithCGImage:CGImageCreateWithMask(grayImage, mask) scale:image.scale orientation:image.imageOrientation];

    // release the CG images
    CGImageRelease(grayImage);
    CGImageRelease(mask);

    // return the new grayscale image
    return grayScaleImage;

    /* changes end here */
    }

    • This code works like a charm on iPad, but on iPhone 3GS the transparent pixels are still becoming black..

      • I can’t see any reason as to why it should not work on the iPhone 3GS – it has worked for me on the 3GS.
        I don’t think it is a device dependent thing – perhaps the problem is that the UIImage that you are using on the 3GS is not actually transparent, but has the same background colour as the background?
        Or perhaps it is to do with the iOS version?

  4. Awesome!!! Short and sweet tutorial. Thank you very much

Comments are closed.