Frage

Ich versuche, eine kleine Anwendung zu entwickeln. Darin muss ich die Farbe eines Pixels in einem UIView erkennen. Ich habe ein CGPoint die Pixel definieren, was ich brauche. Die Farben des UIView verwenden Coreanimation geändert.

Ich weiß, es gibt einige Möglichkeiten, komplexe Farbinformationen von UIImages zu extrahieren. Ich konnte jedoch keine Lösung für UIViews finden.

In Pseudo-Code Ich bin auf der Suche nach so etwas wie

pixel = [view getPixelAtPoint:myPoint];
UIColor *mycolor = [pixel getColor];

Jeder Eingang sehr geschätzt.

War es hilfreich?

Lösung

Es ist ziemlich schrecklich und langsam. Grundsätzlich Sie einen Bitmap-Kontext mit einem Hintergrundspeicher erstellen Sie zuzuteilen so kann man den Speicher eingelesen, dann machen Sie die Ansichten Schicht in dem Kontext und lesen die entsprechende Stelle im RAM.

Wenn Sie wissen, wie es für ein Bild tun, schon können Sie etwas tun:

- (UIImage *)imageForView:(UIView *)view {
  UIGraphicsBeginImageContext(view.frame.size);
  [view.layer renderInContext: UIGraphicsGetCurrentContext()];
  UIImage *retval = UIGraphicsGetImageFromCurrentImageContext(void);
  UIGraphicsEndImageContext();

  return retval;
}

Und dann werden Sie ein Bild erhalten, wo Sie die Pixeldaten erhalten können. Ich bin sicher, dass der Mechanismus Du mit Bildern für den Umgang hast beinhaltet sie in einen Kontext ohnehin machen, so dass Sie, dass mit diesem und ausklammern der eigentlichen Bild Schöpfung verschmelzen können. Wenn Sie also das könnte nehmen und entfernen Sie das Bit, wo Sie das Bild laden und ersetzen Sie es mit dem Kontext machen:

[view.layer renderInContext: UIGraphicsGetCurrentContext()];

Sie sollten gut sein.

Andere Tipps

Hier ist effizientere Lösung:

// UIView+ColorOfPoint.h
@interface UIView (ColorOfPoint)
- (UIColor *) colorOfPoint:(CGPoint)point;
@end

// UIView+ColorOfPoint.m
#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, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);

    CGContextTranslateCTM(context, -point.x, -point.y);

    [self.layer renderInContext:context];

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    //NSLog(@"pixel: %d %d %d %d", pixel[0], pixel[1], pixel[2], pixel[3]);

    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;
}

@end

Link zu Dateien: https://github.com/ivanzoid/ikit/ Baum / Master / UIView + ColorOfPoint

Eine swift'ified Version von ivanzoid 's Antwort

Swift 3

extension CALayer {

    func colorOfPoint(point:CGPoint) -> CGColor {

        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: -point.x, y: -point.y)

        self.render(in: context!)

        let red: CGFloat   = CGFloat(pixel[0]) / 255.0
        let green: CGFloat = CGFloat(pixel[1]) / 255.0
        let blue: CGFloat  = CGFloat(pixel[2]) / 255.0
        let alpha: CGFloat = CGFloat(pixel[3]) / 255.0

        let color = UIColor(red:red, green: green, blue:blue, alpha:alpha)

        return color.cgColor
    }
}

Swift 2

extension CALayer {

    func colorOfPoint(point:CGPoint)->CGColorRef
    {
        var pixel:[CUnsignedChar] = [0,0,0,0]

        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)

        self.renderInContext(context!)

        let red:CGFloat = CGFloat(pixel[0])/255.0
        let green:CGFloat = CGFloat(pixel[1])/255.0
        let blue:CGFloat = CGFloat(pixel[2])/255.0
        let alpha:CGFloat = CGFloat(pixel[3])/255.0

        let color = UIColor(red:red, green: green, blue:blue, alpha:alpha)

        return color.CGColor
    }

}

auf Basis des zugrunde liegenden CALayer aber leicht übersetzbar zurück zu UIView.

Fixed einige kleinere Fehler

- (UIImage *)imageForView:(UIView *)view {
    UIGraphicsBeginImageContext(view.frame.size);
    [view.layer renderInContext: UIGraphicsGetCurrentContext()];
    UIImage *retval = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return retval;
}

Fügen Sie außerdem

#import <QuartzCore/QuartzCore.h>  

, um die Dateien Meldungen zu vermeiden Warnung.

Das Kombinieren Sie den Code mit dem Code gefunden hier einwandfrei funktioniert.

Swift 4 & 4.2 . Getestet mit XCode 10, iOS 12, Simulator & iPhone 6+ mit iOS 12.1.

Dieser Code funktionieren.

extension UIView {
    func colorOfPoint(point: CGPoint) -> UIColor {
        let colorSpace: CGColorSpace = CGColorSpaceCreateDeviceRGB()
        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)

        var pixelData: [UInt8] = [0, 0, 0, 0]

        let context = CGContext(data: &pixelData, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)

        context!.translateBy(x: -point.x, y: -point.y)

        self.layer.render(in: context!)

        let red: CGFloat = CGFloat(pixelData[0]) / CGFloat(255.0)
        let green: CGFloat = CGFloat(pixelData[1]) / CGFloat(255.0)
        let blue: CGFloat = CGFloat(pixelData[2]) / CGFloat(255.0)
        let alpha: CGFloat = CGFloat(pixelData[3]) / CGFloat(255.0)

        let color: UIColor = UIColor(red: red, green: green, blue: blue, alpha: alpha)

        return color
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top