【问题标题】:How do I erase part of a CALayer?如何擦除 CALayer 的一部分?
【发布时间】:2017-08-30 21:25:37
【问题描述】:

我有一个 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;

【问题讨论】:

  • 你不只是在面具上用.clear画画吗?

标签: ios objective-c xcode calayer erase


【解决方案1】:

你需要使用CALayer的contents属性来编辑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。它可以编译,但会导致带有“不支持的错误”消息的运行时错误。所以我们需要将 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

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

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

再说明:核心图形的y轴是自下而上,与UIKit相反。所以你需要翻转顶部和底部,虽然这是一个简单的任务。

或者如果你有面具的 UIImage(已经编辑),你可以从 UIImage 创建 CGImage 只是用

myCGImage = myUIImage.cgImage

【讨论】:

  • 感谢您的回复,但您能将其转换为 Objective C 吗?
猜你喜欢
  • 2011-05-30
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-09
  • 2013-10-05
相关资源
最近更新 更多