我已经花费了太多时间来尝试解决这个问题,但是还是找不到可行的解决方案。
情况: 1. 在手机上显示了一个“某物”的图片。 2. 在图像顶部放置了一个半透明的(例如蓝色)层,完全覆盖了它。 3. 在此层中存在一个“孔”,该部分完全透明且可移动。
一个例子可能是缩放效果,在其中您可以在图像周围移动这个“孔”。在孔内部,您可以正常看到图像,而在外面则被半透明层覆盖。注意:我正在一个cocos2d层中实现此功能,其中图像由CCSprite表示。如果没有使用cocos,那么这不应该有影响。
问题: 我尝试使用CAShapeLayer和位图作为掩码,但没有任何作用(请参见下面的代码片段)。对于CAShapeLayer,我创建了一个UIBezierPath以获取“孔”,并将其应用于有颜色的层。然而,只有孔显示颜色,而其余部分则透明。使用图像时,掩码根本没有起作用(我不知道为什么)。我甚至尝试过使用掩码来进行掩蔽,以查看是否有效。我还尝试了一些交换颜色的方法……从白色到黑色再到透明,用于填充和背景。
一个简单的解决方案(如果存在),就是反转UIBezierPath的区域。我也尝试过使用路径进行剪辑,但没有成功。
我希望这只是一个简单愚蠢的问题,而我只是忽视了它。也许你们中的其中一个会看到这个问题。我还不关心移动部分。我需要先让实际掩码起作用。示例代码忽略了iPhone SDK和openGL之间的y轴差异。
CAShapeLayer示例:
CGSize winSize = [[CCDirector sharedDirector] winSize];
UIImage* img = [UIImage imageNamed:@"zebra.png"];
CCSprite* spr = [CCSprite spriteWithCGImage:img.CGImage key:@"img"];
spr.position = ccp( winSize.width / 2, winSize.width / 2 );
[self addSprite:spr];
UIBezierPath* path = [UIBezierPath bezierPathWithRect:rectHole];
CAShapeLayer* maskLayer = [CAShapeLayer layer];
maskLayer.bounds = [spr boundingBox];
maskLayer.position = spr.position;
maskLayer.fillColor = [UIColor whiteColor].CGColor;
maskLayer.backgroundColor = [UIColor clearColor].CGColor;
maskLayer.path = path.CGPath;
CALayer* colorLayer = [CALayer layer];
colorLayer.bounds = [spr boundingBox];
colorLayer.position = maskLayer.position;
[colorLayer setMask:maskLayer];
[[[[CCDirector sharedDirector] openGLView] layer] addSublayer:colorLayer];
多层蒙版示例:
CGSize winSize = [[CCDirector sharedDirector] winSize];
UIImage* img = [UIImage imageNamed:@"zebra.png"];
CCSprite* spr = [CCSprite spriteWithCGImage:img.CGImage key:@"img"];
spr.position = ccp( winSize.width / 2, winSize.width / 2 );
[self addSprite:spr];
UIBezierPath* path = [UIBezierPath bezierPathWithRect:rectHole];
CAShapeLayer* maskLayer = [CAShapeLayer layer];
maskLayer.bounds = [spr boundingBox];
maskLayer.position = spr.position;
maskLayer.fillColor = [UIColor whiteColor].CGColor;
maskLayer.backgroundColor = [UIColor clearColor].CGColor;
maskLayer.path = path.CGPath;
UIBezierPath* pathOuter = [UIBezierPath bezierPathWithRect:img.frame];
CAShapeLayer* outerLayer = [CAShapeLayer layer];
outerLayer.bounds = [spr boundingBox];
outerLayer.position = spr.position;
outerLayer.fillColor = [UIColor blackColor].CGColor;
outerLayer.backgroundColor = [UIColor whiteColor].CGColor;
outerLayer = pathOuter.CGPath;
[outerLayer setMask:maskLayer];
CALayer* colorLayer = [CALayer layer];
colorLayer.bounds = [spr boundingBox];
colorLayer.position = outerLayer.position;
[colorLayer setMask:outerLayer];
[[[[CCDirector sharedDirector] openGLView] layer] addSublayer:colorLayer];
图像遮罩示例:
CGSize winSize = [[CCDirector sharedDirector] winSize];
UIImage* img = [UIImage imageNamed:@"zebra.png"];
CCSprite* spr = [CCSprite spriteWithCGImage:img.CGImage key:@"img"];
spr.position = ccp( winSize.width / 2, winSize.width / 2 );
[self addSprite:spr];
CGRect r = [spr boundingBox];
CGSize sz = CGSizeMake( r.size.width, r.size.height );
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef context = CGBitmapContextCreate( NULL, w, h, 8, 0, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaNone );
CGColorSpaceRelease( colorSpace );
CGContextSetFillColorWithColor( context, [UIColor whiteColor].CGColor );
CGContextFillRect( context, r );
CGContextSetFillColorWithColor( context, [UIColor blackColor].CGColor );
CGContextFillRect( context, rectHole );
CGImageRef ref = CGBitmapContextCreateImage( context );
CGContextRelease( context );
CALayer* maskLayer = [CALayer layer];
maskLayer.bounds = [spr boundingBox];
maskLayer.position = spr.position;
[maskLayer setContents:(id)ref];
CALayer* colorLayer = [CALayer layer];
colorLayer.bounds = [spr boundingBox];
colorLayer.position = maskLayer.position;
[colorLayer setMask:maskLayer];
[[[[CCDirector sharedDirector] openGLView] layer] addSublayer:colorLayer];
CGImageRelease( ref );