简体   繁体   中英

Convert image to gray scale

In my application I'm having one UIImageView , there is one UIView of clear background color on top of this UIImageView .

I'm using UIBezierPath to free hand drawing on this UIView so that it appears user is drawing on the UIImage of UIImageView .

I'm adding transparency to the UIBezierPath color.

My question is when I initially load UIImage in UIImageView how to make look that UIImage is of gray scale and when user moves his finger on the screen the original color of the UIImage is showed to the user?

The proper way to do this is to use Core Image, and write your own Core Image filter that operates on the color image. By setting a few properties on the filter, it would know to draw some section in color but convert the other areas to gray scale.

That said this is not a trivial work item. You may be able to hack something else together but it will probably be jerky and not smooth. The Core Image filter works at the same level Core Animation does (near the GPU) so it will work very well if you go that way.

On touch, call this function which returns you grey scaled image. On touches ended, set your original image for UIImageView.

- (UIImage*)imageWithGrayScaleImage:(UIImage*)inputImg
{   
//Creating image rectangle
//CGRect imageRect = CGRectMake(0, 0, inputImg.size.width / (CGFloat)[inputImg scale], inputImg.size.height / (CGFloat)[inputImg scale]);
CGRect imageRect = CGRectMake(0, 0, inputImg.size.width, inputImg.size.height);

//Allocating memory for pixels
int width = imageRect.size.width;
int height = imageRect.size.height;

uint32_t *pixels = (uint32_t*)malloc(width * height * sizeof(uint32_t));

//Clearing the memory to preserve any transparency.(Alpha)
memset(pixels, 0, width * height * sizeof(uint32_t));

//Creating a context with RGBA pixels
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);

//Drawing the bitmap to the context which will fill the pixels memory
CGContextDrawImage(context, imageRect, [inputImg CGImage]);

//Indices as ARGB or RGBA
const int RED = 1;
const int GREEN = 2;
const int BLUE = 3;

for (int y = 0; y < height; y++)
{
    for (int x = 0; x < width; x++)
    {
        uint8_t* rgbaPixel = (uint8_t*)&pixels[y * width + x];

        //Calculating the grayScale value
        uint32_t grayPixel = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];

        //Setting the pixel to gray
        rgbaPixel[RED] = grayPixel;
        rgbaPixel[GREEN] = grayPixel;
        rgbaPixel[BLUE] = grayPixel;
    }
}

//Creating new CGImage from the context with modified pixels
CGImageRef newCGImage = CGBitmapContextCreateImage(context);

//Releasing resources to free up memory
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);

//Creating UIImage for return value
//UIImage* newUIImage = [UIImage imageWithCGImage:newCGImage scale:(CGFloat)[inputImg scale] orientation:UIImageOrientationUp];
UIImage* newUIImage = [UIImage imageWithCGImage:newCGImage];

//Releasing the CGImage
CGImageRelease(newCGImage);

return newUIImage;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM