【发布时间】:2011-08-08 22:28:27
【问题描述】:
我花了太多时间试图解决这个问题,但根本找不到可行的解决方案。
情况: 1. 手机上显示“某物”的图片。 2. 半透明(例如蓝色)层放置在图像顶部,完全覆盖它。 3. 该层中存在一个“洞”,该层的该部分完全透明且可移动。
一个示例可能是缩放效果,您可以在图像周围移动这个“洞”。在洞内你可以正常看到图像,而在洞外则被半透明层覆盖。注意:我在 cocos2d 层中实现这一点,其中图像由 CCSprite 表示。不过,如果没有使用 cocos,应该没关系。
问题: 我尝试使用 CAShapeLayer 和位图作为掩码,但没有任何效果(参见下面的代码 sn-ps)。使用 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 );
【问题讨论】:
-
看看这个类似的问答是否有帮助:[Cut transparent hole in UIView][1] [1]: stackoverflow.com/questions/9711248/…
标签: iphone ios cocos2d-iphone