I know this is a common question and there are a lot of answers of this question. I\'ve used some of this. Although many of them are the same. But the sad thing for me is th
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
}
}
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)
}
}
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
}
First, I'd like to thank the author of this code, it helped me a lot for my game project, as I was looking for this function to do a pixel-perfect hitbox (excluding where the aplha is O). Here's a little update for Swift 5:
// Fonction permettant de retourner les valeurs RGBA d'un pixel d'une vue
func getPixelColor(atPosition:CGPoint) -> UIColor{
var pixel:[CUnsignedChar] = [0, 0, 0, 0];
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: -atPosition.x, y: -atPosition.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);
return color;
}
I had somme issues with pixel.dealloc(4), as in Swift 5 it seems that you can't dealloc with capacity parameter anymore. I removed the (4), but it had some weird behavior (as the dealloc() didn't dealloc the whole array).
I didn't do an extension of UIView as in my project I have my own subclass, but this can be easily done.
The way I implement the code:
// Méthode déterminant si le "touch" est validé par l'objet (par défaut, exclut les zones transparentes et les objets invisibles). A surcharger si nécessaire.
func isHit(atPosition position:CGPoint) -> Bool
{
// Si l'objet n'est pas caché (paramètre isHidden) et si la zone touchée correspond à une zone effectivement dessinée (non transparente), retourne true.
if (!self.isHidden && self.getPixelColor(atPosition: position).cgColor.alpha != 0) {return true}
else {return false}
}
I hope this can help.
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
}
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.