4

J'ai un problème étrange avec CALayer dessin pour l'iPhone. J'ai une couche racine qui ajoute un groupe de sous-couches représentant des "bulles". Le résultat final est censé ressembler à ceci:CALayer et l'anticrénelage CGGradientRef?

http://www.expensivedna.com/IMG_0018.PNG http://www.expensivedna.com/IMG_0018.PNG

Le problème est que je ne peux pas sembler obtenir la couche d'anti-alias (notez les crénelage sur les bulles). Mon code d'écraser drawInContext pour la CALayer bulle est la suivante:

- (void)drawInContext:(CGContextRef)theContext{ 
CGContextSetAllowsAntialiasing(theContext, true); 
CGContextSetShouldAntialias(theContext, true); 

size_t num_locations = 2; 
CGFloat locations[2] = { 0.0, 1.0 }; 
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.5, // Start color 
          1.0, 1.0, 1.0, 0.0 }; // End color 
CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB(); 
CGGradientRef glossGradient = 
CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations); 

CGPoint topCenter = CGPointMake(25, 20); 
CGPoint midCenter = CGPointMake(25, 25); 
CGContextDrawRadialGradient(theContext, glossGradient, midCenter, 20, topCenter, 10, kCGGradientDrawsAfterEndLocation); 

}

Maintenant, la chose vraiment étrange est que si je modifie un peu le code de dessin pour dessiner uniquement les cercles rouges normaux comme suit:

- (void)drawInContext:(CGContextRef)theContext{ 
CGContextSetAllowsAntialiasing(theContext, true); 
CGContextSetShouldAntialias(theContext, true); 

CGContextSetFillColorWithColor(theContext, [UIColor redColor].CGColor); 
CGContextFillEllipseInRect(theContext, CGRectMake(0, 0, 40,40)); 
} 

Tout semble anticrénelage OK:

http://www.expensivedna.com/IMG_0017.PNG http://www.expensivedna.com/IMG_0017.PNG

Je n'arrive pas à comprendre ce comportement apparemment étrange. Est-ce qu'il me manque une différence entre les gradients anti-crénelage et les cercles normaux?

Merci les gars.

Répondre

4

Merci les gars. Il s'avère donc que la réponse est une combinaison de vos deux réponses (coob et Alex). Fondamentalement, il semble que la fonction CGDrawRadialGradient n'ait qu'un alias au niveau du cercle de départ, pas celui qui se termine. Comme je veux crénelage « bords » sur les deux, j'ai mis la fonction à tirer de l'intérieur qui prend en charge le premier « bord », mais produit les éléments suivants:

Step 1

Ensuite, je pince la l'image comme suggéré par COOB et qui donne un aliasing agréable autour du bord final de la bulle:

Step 2

semble assez bon pour moi!

- (void)drawInContext:(CGContextRef)theContext{ 
CGContextSetAllowsAntialiasing(theContext, true); 
CGContextSetShouldAntialias(theContext, true); 

size_t num_locations = 2; 
CGFloat locations[2] = { 0.0, 1.0 }; 
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.0, // Start color 
       1.0, 1.0, 1.0, 0.5 }; // End color 
CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB(); 
CGGradientRef glossGradient = 
CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations); 

CGContextAddEllipseInRect(theContext, CGRectMake(5, 5, 40, 40)); 
CGContextClip(theContext); 

CGPoint topCenter = CGPointMake(25, 20); 
CGPoint midCenter = CGPointMake(25, 25); 
CGContextDrawRadialGradient(theContext, glossGradient, topCenter, 10, midCenter, 20, kCGGradientDrawsAfterEndLocation); 

}

0

peut-être essayer d'abandonner le kCGGradientDrawsAfterEndLocation? Il pourrait faire quelque chose de bizarre avec l'alpha

2

Jeff - rendre topCenter un peu plus loin et utiliser CGContextClipToMask avec un masque circulaire. Editer: En fait, une façon bien meilleure de le faire est d'utiliser un chemin de détourage vectoriel en utilisant CGContextClip.

Edit 2: Exemple de code:

CGContextAddEllipseInRect(theContext, CGRectMake(20, 20, 10, 10)); 
CGContextClip(theContext); 

Ajouter ce avant de tirer votre dégradé, et d'en tirer un peu plus loin.

+0

conseil: Nous avons dû encadré mon rect par un 1 point d'éliminer complètement crénelage ici. – mattorb