How to get the pixel color on touch?
Swift 4, Xcode 9 - With a UIImageView Extension
This is a combination of all of the answers above but in an extension
extension UIImageView {
func getPixelColorAt(point:CGPoint) -> UIColor{
let pixel = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: 4)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
let context = CGContext(data: pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
context!.translateBy(x: -point.x, y: -point.y)
layer.render(in: context!)
let color:UIColor = UIColor(red: CGFloat(pixel[0])/255.0,
green: CGFloat(pixel[1])/255.0,
blue: CGFloat(pixel[2])/255.0,
alpha: CGFloat(pixel[3])/255.0)
pixel.deallocate(capacity: 4)
return color
}
}
How to use
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let point = touch?.location(in: view) {
let color = myUIImageView.getPixelColorAt(point: point)
print(color)
}
}
Great answer rdelmar this helped me A LOT!
Here is how I did the above in Swift:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
{
var touch:UITouch = event.allTouches()!.anyObject() as UITouch
var loc = touch.locationInView(self)
var color:UIColor = getPixelColorAtPoint(loc)
println(color)
}
//returns the color data of the pixel at the currently selected point
func getPixelColorAtPoint(point:CGPoint)->UIColor
{
let pixel = UnsafeMutablePointer<CUnsignedChar>.alloc(4)
var colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.PremultipliedLast.rawValue)
let context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, bitmapInfo)
CGContextTranslateCTM(context, -point.x, -point.y)
layer.renderInContext(context)
var color:UIColor = UIColor(red: CGFloat(pixel[0])/255.0, green: CGFloat(pixel[1])/255.0, blue: CGFloat(pixel[2])/255.0, alpha: CGFloat(pixel[3])/255.0)
pixel.dealloc(4)
return color
}
Thank you for @Aggressor's post the code above
Swift 2.1
func getPixelColorAtPoint(point:CGPoint) -> UIColor{
let pixel = UnsafeMutablePointer<CUnsignedChar>.alloc(4)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)
let context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, bitmapInfo.rawValue)
CGContextTranslateCTM(context, -point.x, -point.y)
view.layer.renderInContext(context!)
let color:UIColor = UIColor(red: CGFloat(pixel[0])/255.0, green: CGFloat(pixel[1])/255.0, blue: CGFloat(pixel[2])/255.0, alpha: CGFloat(pixel[3])/255.0)
pixel.dealloc(4)
return color
}
Swift 3, Xcode Version 8.2 (8C38) and Swift 4, Xcode Version 9.1 (9B55)
func getPixelColorAtPoint(point:CGPoint, sourceView: UIView) -> UIColor{
let pixel = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: 4)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
let context = CGContext(data: pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
var color: UIColor? = nil
if let context = context {
context.translateBy(x: -point.x, y: -point.y)
sourceView.layer.render(in: context)
color = UIColor(red: CGFloat(pixel[0])/255.0,
green: CGFloat(pixel[1])/255.0,
blue: CGFloat(pixel[2])/255.0,
alpha: CGFloat(pixel[3])/255.0)
pixel.deallocate(capacity: 4)
}
return color
}
This is the one I've used, and it looks simpler than the methods you've tried.
In my custom view class, I have this:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint loc = [touch locationInView:self];
self.pickedColor = [self colorOfPoint:loc];
}
colorOfPoint is a method in a category on UIView, with this code:
#import "UIView+ColorOfPoint.h"
#import <QuartzCore/QuartzCore.h>
@implementation UIView (ColorOfPoint)
-(UIColor *) colorOfPoint:(CGPoint)point
{
unsigned char pixel[4] = {0};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixel,
1, 1, 8, 4, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
CGContextTranslateCTM(context, -point.x, -point.y);
[self.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];
return color;
}
Don't forget to import the category into the custom view class and add the QuartzCore framework.
Trivial note for 2013: cast that last argument as (CGBitmapInfo) to avoid an implicit conversion warning: example here. Hope it helps.