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.
You're malloc
ing 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.