5
votes

I have successfully converted an Image to Grayscale, I want to revert the Grayscale Image back to RGB Image. Please help. Thanks in advance.

-(UIImage *) toGrayscale
    {

    const int RED = 1;
    const int GREEN = 2;
    const int BLUE = 3;

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

        int width = imageRect.size.width;
        int height = imageRect.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
                uint8_t gray = (uint8_t) ((30 * rgbaPixel[RED] + 59 * rgbaPixel[GREEN] + 11 * rgbaPixel[BLUE]) / 100);

                // 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
                                                     scale:self.scale
                                               orientation:UIImageOrientationUp];

        // we're done with image now too
        CGImageRelease(image);

        return resultUIImage;
}
1
Grayscale to RGB Image?nicael
I want to revert grayscale image to original imageArvind
You should keep the original image saved and not "overwrite" it with the new grayscale image. When you need it again, just use the original image.Mihai Popa
If you ever manage to revert a greyscale back to colour, you will be a very rich man. Imagine how all movies recorded in B&W, can turn back into colour. ;)BlueVoodoo
You can't convert. To revert just save original image, as Mihai Popa pointednicael

1 Answers

7
votes

To answer the question about converting, your code for grayscale:

uint8_t gray = (uint8_t) ((30 * rgbaPixel[RED] + 59 * rgbaPixel[GREEN] + 11 * rgbaPixel[BLUE]) / 100);

gives the relationship:

S = 0.3R + 0.59G + 0.11B

Go go from RGB to S involves solving for one unknown (S) with one equation (fine!). To convert back is like trying for three unknowns (RGB) given one equation which isn't possible.

One hack to doing a grayscale colorisation is to consider grayscale as just intensity, and set

R = G = B = S - but this isn't going to restore your colors correctly (obviously). So in short, conversion to grayscale is an irreversible function, like squaring a number (was it positive or negative?) - information is lost and can't be retrieved.