Spędziłem zbyt wiele czasu, próbując to zrozumieć i po prostu nie mogę znaleźć praktycznego rozwiązania.Utwórz maskę warstwy z niestandardowym otworem
Sytuacja: 1. Obraz "czegoś" jest wyświetlany na telefonie. 2. Półprzezroczysta (np. Niebieska) warstwa jest umieszczona na górze obrazu, całkowicie ją zakrywając. 3. "Otwór" w tej warstwie istnieje tam, gdzie ta część warstwy jest całkowicie przezroczysta i ruchoma.
Przykładem może być efekt powiększenia, w którym przesuwa się tę "dziurę" wokół obrazu. Wewnątrz otworu widać normalnie obraz, a na zewnątrz pokrywa go półprzezroczysta warstwa. UWAGA: Wdrażam to w warstwie cocos2d, gdzie obraz jest reprezentowany przez CCSprite. Nie powinno to jednak mieć znaczenia, jeśli nie używa się cocos.
Problem: Próbowałem za pomocą CAShapeLayer i bitmapy jako maski, ale nic nie działa (patrz fragmenty kodu poniżej). Za pomocą CAShapeLayer tworzę ścieżkę UIBezierPath dla "otworu" i stosuję ją do kolorowej warstwy. Jednak tylko dziura pokazuje kolor, podczas gdy reszta jest przezroczysta. Z obrazem maska po prostu nie działa (nie mam pojęcia dlaczego). Próbowałem nawet maski maskujące, żeby sprawdzić, czy to zadziała. Próbowałem również zamieniać kolory wokół ... z białego na czarny, aby wyczyścić wypełnienie i tło.
Prostym rozwiązaniem, gdyby istniało, byłoby odwrócenie obszaru UIBezierPath. Próbowałem również wycinania, używając ścieżki ... ale bez powodzenia.
Mam nadzieję, że to jest coś prostego - głupiego, że po prostu przeoczyłem. Być może któryś z was to zobaczy. Część ruchoma, z którą nie jestem związany. Najpierw muszę sprawić, żeby maska zadziałała. Przykładowy kod ignoruje różnice osi Y między iPhone SDK i OpenGL.
CAShapeLayer Przykład:
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];
wielowarstwowy Maska Przykład:
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];
Obraz Maska Przykład:
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);
Zobacz, czy to podobne pytanie i odpowiedź help: [Wytnij otwór w przejrzysty UIView] [1] [1]: http://stackoverflow.com/questions/9711248/cut-transparent-hole- in-uiview/30994705 # 30994705 – dichen