Créer un masque de calque avec des trous en forme de
J'ai passé trop de temps à essayer de comprendre cela et ne peut tout simplement pas trouver une solution viable.
Situation:
1. Une image de "quelque chose" est affiché sur le téléphone.
2. Semi-transparent (bleu, par exemple) de la couche est placée sur le haut de l'image, couvrant complètement.
3. Un "trou" dans cette couche existe lorsque que la partie de la couche est complètement transparent et amovible.
Un exemple pourrait être un effet de zoom lorsque vous déplacez ce "trou" autour de l'image. À l'intérieur du trou, vous pouvez voir l'image normalement, alors que dehors, il est couvert par la couche semi-transparente. NOTE: je me suis mise en œuvre de cette dans un cocos2d couche, où l'image est représentée par un CCSprite. Il ne devrait pas, toutefois, si aucune de coco est utilisée.
Problème:
J'ai essayé d'utiliser CAShapeLayer et les bitmaps, des masques, mais rien ne fonctionne (voir des extraits de code ci-dessous). Avec le CAShapeLayer, j'ai créer un UIBezierPath pour le "trou" et de l'appliquer à la couleur de la couche. Toutefois, seul le trou montre la couleur, tandis que le reste est transparent. Avec une image, le masque est tout simplement ne fonctionne pas (je n'ai aucune idée pourquoi). J'ai même essayé de masquage des masques pour voir si cela fonctionnerait. J'ai aussi essayé en échangeant les couleurs autour...du blanc au noir au clair pour le remplissage et l'arrière-plan.
Une solution simple, si elle existait, serait d'inverser le domaine de la UIBezierPath. J'ai essayé de détourage, ainsi, en utilisant le chemin d'accès...mais pas de chance.
J'espère que c'est quelque chose de simple, stupide que je suis tout simplement dominant. Peut-être l'un de vous va voir ça. La partie qui bouge, je ne suis pas, encore, concernés par. J'ai besoin d'obtenir le véritable masque de travail en premier. L'exemple de code est ignorant de l'axe des différences entre le SDK de l'iPhone et openGL.
CAShapeLayer Exemple:
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];
Plusieurs Masque De Calque Exemple:
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];
Le Masque De L'Image Exemple:
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 );
OriginalL'auteur GtotheB | 2011-04-19
Vous devez vous connecter pour publier un commentaire.
Je suis revenue plus tard après l'apprentissage d'autres techniques graphiques.
La solution est plus proche de l'Multiples Masque de Calque Exemple ci-dessus.
Cependant, au lieu de créer une couche intérieure et extérieure, vous devez combiner les deux voies en une seule UIBezierPath dans des directions opposées.
Par exemple, créer un chemin d'accès de l'intérieur de la zone de recadrage (CW). REMARQUE: x,y,w,h se référant à l'origine et la taille du "trou".
Ensuite, ajouter le même chemin que l'extérieur de la zone dans la direction opposée (CCW). REMARQUE: x,y,w,h se référant à l'origine et la taille de l'extérieur rect.
Ce chemin est ensuite appliquée à une couche (maskLayer), qui est utilisé comme masque sur la couche finale (colorLayer). Le "outerLayer" n'est pas nécessaire.
appendPath:
- créer un chemin d'accès unique à un rect de l'ensemble de l'image, puis ajouter les chemins de représenter l'individu trou(s). Modifier la règle de remplissage de même bizarre et hop.Bon point. Mais ne serait-ce pas entraîner la création d'un chemin d'accès de la même façon, de toute façon? I. e., vous auriez du faire le même code pour ajouter des points, mais sur un autre chemin, puis d'ajouter ce chemin...contre l'ajoutant le chemin original directement. Votre approche serait probablement plus lisible.
Je pense que j'aurais été en commentant sur la question, dans les multiples masques exemple.
Merci a utilisé cette technique pour en tirer de l'SIG complexes polygones (figurant trous) stockées dans une base Spatialite. L'extraction de la géométrie spécifique avec des fonctions de requête: ExteriorRing(Géométrie), InteriorRingN(Géométrie, N) et ST_NRings(Géométrie)
OriginalL'auteur GtotheB