Search code examples
pixelrgb

Getting RGB of a pixel in touchesMoved delegate


I have created a page that picks RGB values of a pixel. It allows user to move his finger and choose the pixel color of the selected image. Also setting the RGB hence obtained, to the small image view showing his selection.

Here is the piece of code.

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];

    // Get Touch location
    CGPoint touchLocation = [touch locationInView:touch.view];

    // Set touch location's center to ImageView
    if (CGRectContainsPoint(imageViewColorPicker.frame, touchLocation))
    {
        imageViewColorPicker.center = touchLocation;

        CGImageRef image = [imageViewSelectedImage.image CGImage];
        NSUInteger width = CGImageGetWidth(image);
        NSUInteger height = CGImageGetHeight(image);

        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

        unsigned char *rawData = malloc(height * width * 4);
        NSUInteger bytesPerPixel = 4;
        NSUInteger bytesPerRow = bytesPerPixel * width;
        NSUInteger bitsPerComponent = 8;

        CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
        CGColorSpaceRelease(colorSpace);

        CGContextDrawImage(context, CGRectMake(0, 0, width, height),image);
        CGContextRelease(context);

        int byteIndex = (bytesPerRow * (int)touchLocation.y) + (int)touchLocation.x * bytesPerPixel;
        red = rawData[byteIndex];
        green = rawData[byteIndex + 1];
        blue = rawData[byteIndex + 2];
        alpha = rawData[byteIndex + 3];


        imgPixelColor.backgroundColor=[UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:alpha];
    }
}

It is solving my problem. But the issue is it sometimes crashes during finger move showing Received Memory Warning message 3 times in the log window.

Am I doing something wrong? Is there any other way to get RGB's to solve this kind of problem? Any library if available ?

Quick help is appreciated.


Solution

  • You're mallocing the pixel buffer for the graphics context (rawData), but you never free it, so you're basically leaking a copy of the entire image, every time a touch moves (this can be a lot of memory pretty quickly).

    Add this at the end of your if-statement.

    free(rawData);
    

    Btw, you may want to consider creating the bitmap context just once and reusing it. It's pretty wasteful to redraw the image every time a touch moves, if it stays the same anyway.