2017-08-30 7 views
1

Ich habe eine UIImageView, die ich mit einer transparenten Maske mit CALayer abdecken.Wie lösche ich einen Teil eines CALayers?

Ich möchte Teile des CALayer mit einem Pinsel aus einem UIImage löschen können.

Hier ist mein Code so weit für die ersten 2 Schritte.

topImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 
topImageView.image = [UIImage imageNamed:@"testimage2.PNG"]; 
topImageView.contentMode = UIViewContentModeScaleAspectFill; 
topImageView.userInteractionEnabled = FALSE; 
[self addSubview:topImageView]; 

CALayer *mask = [CALayer layer]; 
mask.bounds = CGRectMake(0, 0, topImageView.frame.size.width, topImageView.frame.size.height); 
topImageView.layer.mask = mask; 

enter image description here

+0

erstellen Sind Sie nicht nur Zeichnung mit '.clear' auf der Maske? – matt

Antwort

0

Sie benötigen Inhalte Eigentum von CALayer verwenden Teil CALayer zu bearbeiten.

Mehrere Möglichkeiten, Inhalte vorzubereiten. Beispielsweise erstellen Sie Bitmap von RGBA in UInt8-Array und erstellen dann CGImage daraus.

Swift:

func createCGImageFromBitmap(bitmap: UnsafeMutablePointer<UInt8>, width: Int, height: Int) -> CGImage { 
    let colorSpace = CGColorSpaceCreateDeviceRGB() 
    let context = CGContext(data: bitmap, width: width, height: height, bitsPerComponent: 8, bytesPerRow: width * 4, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) 
    let imageRef = context?.makeImage() 
    return imageRef! 
} 

Objective-C:

CGImageRef createCGImageFromBitmap(unsigned char *bitmap, int width, int height) { 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(bitmap, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast); 
    CGImageRef imageRef = CGBitmapContextCreateImage(context); 
    return imageRef; 
} 

Hier ist nur ein Bitmap-Speicher-Array in RGBARGBA ..., deren Größe Breite * Höhe * 4 Bytes. Hinweis: Ich habe die ursprüngliche Antwort aktualisiert, da ich festgestellt habe, dass CGContext (Daten: ..) (swift)/CGBitmapContextCreate (obj-c) last/kCGImageAlphaLast nicht akzeptiert. Es kompiliert, verursacht aber einen Laufzeitfehler mit Meldung "nicht unterstützter Fehler". Also müssen wir Alpha zu RGB vormultiplizieren.

Dann

Swift:

let screenScale = Int(UIScreen.main.scale) 
    let widthScaled = width * screenScale 
    let heightScaled = height * screenScale 
    let memSize = widthScaled * heightScaled * 4 
    let myBitmap = UnsafeMutablePointer<UInt8>.allocate(capacity: memSize) 
    // set RGBA of myBitmap. for your case, alpha of erased area gets zero 
    ..... 
    let imageRef = createCGImageFromBitmap(bitmap: myBitmap, width: widthScaled, height: heightScaled) 
    myBitmap.deallocate(capacity: memSize) 
    myCALayer.contents = imageRef 

Objective-C:

int screenScale = (int)[[UIScreen mainScreen] scale]; 
    int widthScaled = width * screenScale; 
    int heightScaled = height * screenScale; 
    int memSize = widthScaled * heightScaled * 4; 
    unsigned char *myBitmap = (unsigned char *)malloc(memSize); 
    // set RGBA of myBitmap. for your case, alpha of erased area gets zero 
    ..... 
    CGImageRef imageRef = createCGImageFromBitmap(bitmap, width, height); 
    free(myBitmap); 
    myCALayer.contents = CFBridgingRelease(imageRef); 

Seit Core Graphics findet nicht Retina Display berücksichtigt, müssen wir Bitmap-Größe manuell skalieren. Sie können die Skalierung mit UIScreen.main.scale erhalten.

Noch ein Hinweis: Y-Achse der Core-Grafik ist von unten nach oben, was gegenüber UIKit ist. Du musst also oben und unten umdrehen, obwohl es eine einfache Aufgabe ist.

Oder wenn Sie UIImage der Maske (bereits bearbeitet) haben, können Sie CGImage von UIImage nur mit

myCGImage = myUIImage.cgImage 
+0

Danke für die Antwort, aber könntest du das in Objective C umwandeln? –

+0

Ich habe meine Antwort mit Objective-C aktualisiert. – beshio

Verwandte Themen