如何删除部分CALayer?

时间:2017-08-30 21:25:37

标签: ios objective-c xcode calayer erase

我有一个UIImageView,我使用CALayer覆盖透明蒙版。

我希望能够使用UIImage制作的画笔擦除CALayer的部分内容。

这是我前面两步的代码。

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

1 个答案:

答案 0 :(得分:0)

您需要使用CALayer的内容属性来编辑CALayer的一部分。

准备内容的几种方法。 例如,您在UInt8数组中创建RGBA的位图,然后从中创建CGImage。

夫特:

Do
    WindowTitle = "FOLDERNAME"
    Set shell = CreateObject("WScript.Shell") 
    success = shell.AppActivate(WindowTitle)
    If success Then shell.SendKeys "%{F4}" 
Loop

目标-C:

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

这里,位图只是RGBARGBA ...中的一个内存数组,其大小为宽*高* 4字节。注意我更新了原始答案,因为我意识到CGContext(数据:..)(swift)/ CGBitmapContextCreate(obj-c)不接受last / kCGImageAlphaLast。它编译但导致运行时错误w /&#34;不支持的错误&#34;信息。所以我们需要将alpha预乘以RGB。

然后,

夫特:

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

目标-C:

    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

由于Core Graphics没有考虑Retina显示,我们需要手动缩放位图大小。您可以使用UIScreen.main.scale进行缩放。

还有一点需要注意:核心图形的y轴是从下到上,与UIKit相反。所以你需要翻转顶部和底部,尽管这是一项简单的任务。

或者如果你有掩码的UIImage(已经编辑过),你可以用

从UIImage创建CGImage
    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);