在 touchesMoved 委托中获取像素的 RGB
Posted
技术标签:
【中文标题】在 touchesMoved 委托中获取像素的 RGB【英文标题】:Getting RGB of a pixel in touchesMoved delegate 【发布时间】:2013-05-22 10:21:11 【问题描述】:我创建了一个选择像素 RGB 值的页面。它允许用户移动他的手指并选择所选图像的像素颜色。还将因此获得的 RGB 设置为显示他的选择的小图像视图。
这是一段代码。
- (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];
它正在解决我的问题。但问题是它有时会在手指移动时崩溃,在日志窗口中显示 3 次 Received Memory Warning
消息。
我做错了吗?有没有其他方法可以让 RGB 解决此类问题?有没有图书馆?
感谢您的快速帮助。
【问题讨论】:
【参考方案1】:你malloc
ing 图形上下文的像素缓冲区 (rawData
),但你从来没有 free
它,所以你基本上是在泄漏整个图像的副本,每次触摸移动 (这可能很快就会占用大量内存)。
在 if 语句的末尾添加。
free(rawData);
顺便说一句,您可能需要考虑只创建一次位图上下文并重复使用它。每次触摸移动时都重新绘制图像,如果它始终保持不变的话,那是非常浪费的。
【讨论】:
感谢 man..释放 (rawData) 有助于避免崩溃。但是,您能否详细说明如何重用 context 。我这样做是我猜错了: if(!context) context= CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); CGContextDrawImage(context, CGRectMake(0, 0, width, height),image); CGContextRelease(上下文);另外,由于我一次又一次地绘制图像,因此移动图像视图以选择颜色的工作非常缓慢。请建议,【参考方案2】:@David:RinoTom 是对的。将您的询问作为答案发布是没有意义的。
无论如何,回到您的问题,我为这个问题创建了一个替代解决方案。我使用平移手势移动视图并使用以下方法选择其中心点的 RGB:
-(UIColor *)colorOfTappedPoint:(CGPoint)point
unsigned char pixel[4] = 0;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, kCGImageAlphaPremultipliedLast);
CGContextTranslateCTM(context, -point.x, -point.y);
[self.view.layer renderInContext:context];
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
UIColor *color = [UIColor colorWithRed:pixel[0]/255.0 green:pixel[1]/255.0 blue:pixel[2]/255.0 alpha:pixel[3]/255.0];
red = pixel[0];
green = pixel[1];
blue = pixel[2];
alpha = pixel[3];
NSLog(@"%d %d %d %d",red,green,blue,alpha);
return color;
希望这会有所帮助。
【讨论】:
以上是关于在 touchesMoved 委托中获取像素的 RGB的主要内容,如果未能解决你的问题,请参考以下文章
SetNeedsDisplay导致应用程序在TouchesMoved事件中崩溃
如何在 Swift 和 SpriteKit 中使用 UISwipeGestureRecognizer 而不是 touchesMoved?