Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert image to grayscale

I am trying to convert an image into grayscale in the following way:

#define bytesPerPixel 4 #define bitsPerComponent 8  -(unsigned char*) getBytesForImage: (UIImage*)pImage {     CGImageRef image = [pImage CGImage];     NSUInteger width = CGImageGetWidth(image);     NSUInteger height = CGImageGetHeight(image);      NSUInteger bytesPerRow = bytesPerPixel * width;      CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();     unsigned char *rawData = malloc(height * width * 4);     CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);     CGColorSpaceRelease(colorSpace);      CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);     CGContextRelease(context);      return rawData; }  -(UIImage*) processImage: (UIImage*)pImage {        DebugLog(@"processing image");     unsigned char *rawData = [self getBytesForImage: pImage];      NSUInteger width = pImage.size.width;     NSUInteger height = pImage.size.height;      DebugLog(@"width: %d", width);     DebugLog(@"height: %d", height);      NSUInteger bytesPerRow = bytesPerPixel * width;      for (int xCoordinate = 0; xCoordinate < width; xCoordinate++)     {         for (int yCoordinate = 0; yCoordinate < height; yCoordinate++)         {             int byteIndex = (bytesPerRow * yCoordinate) + xCoordinate * bytesPerPixel;              //Getting original colors             float red = ( rawData[byteIndex] / 255.f );             float green = ( rawData[byteIndex + 1] / 255.f );             float blue = ( rawData[byteIndex + 2] / 255.f );              //Processing pixel data             float averageColor = (red + green + blue) / 3.0f;              red = averageColor;             green = averageColor;             blue = averageColor;              //Assigning new color components             rawData[byteIndex] = (unsigned char) red * 255;             rawData[byteIndex + 1] = (unsigned char) green * 255;             rawData[byteIndex + 2] = (unsigned char) blue * 255;           }     }      NSData* newPixelData = [NSData dataWithBytes: rawData length: height * width * 4];     UIImage* newImage = [UIImage imageWithData: newPixelData];      free(rawData);      DebugLog(@"image processed");      return newImage;  } 

So when I want to convert an image I just call processImage:

imageToDisplay.image = [self processImage: image]; 

But imageToDisplay doesn't display. What may be the problem?

Thanks.

like image 266
Ilya Suzdalnitski Avatar asked Aug 19 '09 09:08

Ilya Suzdalnitski


People also ask

How do I convert a color image to grayscale online?

A simple browser-based Joint Photographic Experts Group photo grayscaler. Just paste your JPEG picture in the input area and you will instantly get a grayscale version of this JPEG. Fast, free, and without intrusive ads. Import a color JPG photo, get a grayscale JPG photo.

Can convert images from RGB mode directly to grayscale?

I = rgb2gray( RGB ) converts the truecolor image RGB to the grayscale image I . The rgb2gray function converts RGB images to grayscale by eliminating the hue and saturation information while retaining the luminance. If you have Parallel Computing Toolbox™ installed, rgb2gray can perform this conversion on a GPU.


1 Answers

I needed a version that preserved the alpha channel, so I modified the code posted by Dutchie432:

@implementation UIImage (grayscale)  typedef enum {     ALPHA = 0,     BLUE = 1,     GREEN = 2,     RED = 3 } PIXELS;  - (UIImage *)convertToGrayscale {     CGSize size = [self size];     int width = size.width;     int height = size.height;      // the pixels will be painted to this array     uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));      // clear the pixels so any transparency is preserved     memset(pixels, 0, width * height * sizeof(uint32_t));      CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();      // create a context with RGBA pixels     CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,                                                   kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);      // paint the bitmap to our context which will fill in the pixels array     CGContextDrawImage(context, CGRectMake(0, 0, width, height), [self CGImage]);      for(int y = 0; y < height; y++) {         for(int x = 0; x < width; x++) {             uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];              // convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale             uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];              // set the pixels to gray             rgbaPixel[RED] = gray;             rgbaPixel[GREEN] = gray;             rgbaPixel[BLUE] = gray;         }     }      // create a new CGImageRef from our context with the modified pixels     CGImageRef image = CGBitmapContextCreateImage(context);      // we're done with the context, color space, and pixels     CGContextRelease(context);     CGColorSpaceRelease(colorSpace);     free(pixels);      // make a new UIImage to return     UIImage *resultUIImage = [UIImage imageWithCGImage:image];      // we're done with image now too     CGImageRelease(image);      return resultUIImage; }  @end 
like image 150
Cam Avatar answered Sep 27 '22 17:09

Cam