2017-08-30 3 views
1

私はCALayerを使用して透明マスクでカバーするUIImageViewを持っています。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

でUIImageからCGImageを作成することができますが、あなただけのマスク上の '.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! 
} 

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

、ビットマップのサイズは、幅*高さ* 4バイトとなっているRGBARGBAにだけ、メモリアレイ...、です。私はCGContext(data:..)(swift)/ CGBitmapContextCreate(obj-c)が最後の/ kCGImageAlphaLastを受け入れないことに気づいたので、私は元の解答を更新しました。それはコンパイルされますが、実行時に「サポートされていないエラー」メッセージが表示されます。 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を使ってスケーリングを得ることができます。

もう1つの注意:コアグラフィックスのy軸は下から上に向いており、これはUIKitの反対です。だから、単純な作業ですが、上と下を反転する必要があります。

それとも、マスク(すでに編集済み)のUIImageを持っている場合、あなただけの

myCGImage = myUIImage.cgImage 
+0

返信いただきありがとうございますが、これをObjective Cに変換できますか? –

+0

私はObjective-Cで自分の答えを更新しました。 – beshio

関連する問題