2017-08-30 77 views
1

我有一個UIImageView,使用CALayer覆蓋透明蒙版。如何擦除CALayer的一部分?

我希望能夠用UIImage製作的畫筆擦除CALayer的各個部分。

這是我的代碼到目前爲止的前2個步驟。

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

你不只是在光罩'.clear'在畫什麼? – matt

回答

0

您需要使用內容的CALayer屬性編輯的CALayer的一部分。

準備內容的幾種方法。 例如,您可以在UInt8數組中創建RGBA的位圖,然後從中創建CGImage。

夫特:

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

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

在此,位圖是剛剛在RGBARGBA存儲器陣列...,其中的大小是寬度×高度×4個字節。注意我更新了原始答案,因爲我意識到CGContext(data:..)(swift)/ CGBitmapContextCreate(obj-c)不接受last/kCGImageAlphaLast。它編譯但會導致運行時錯誤w /「不支持的錯誤」消息。所以我們需要預先將alpha乘以RGB。

然後,

斯威夫特:

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

由於核芯顯卡不帶Retina顯示屏考慮,我們需要手動縮放位圖大小。您可以使用UIScreen.main.scale進行縮放。

還有一點需要注意:核心圖形的y軸是從下到上,與UIKit相反。所以你需要翻轉頂部和底部,儘管這是一個簡單的任務。

或者,如果你有面具(已編輯)的UIImage的,你可以從UIImage的創建CGImage只是

myCGImage = myUIImage.cgImage 
+0

感謝您的回覆,但您是否可以將其轉換爲Objective C? –

+0

我用Objective-C更新了我的答案。 – beshio