Arrondir les coins d'une UIImage

apocaalypsoapocaalypso Membre
juin 2010 modifié dans Actualités #1
Bonjour,

Je voudrais vous faire partager ce petit bout de code assez pratique qui permet d'arrondir les coins d'une UIImage en choisissant le radius. Je l'ai eu grâce à  ce blog : http://blog.sallarp.com/iphone-uiimage-round-corners/

- Tout d'abord, créez les .h et .m d'un NSObject, nommez-le ImageRoundedCorners ou comme vous le souhaitez
- dans le .h, ajoutez les méthodes :
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight);<br />+(UIImage *)makeRoundCornerImage : (UIImage*) img : (int) cornerWidth : (int) cornerHeight;<br />

- dans le .m :
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight)<br />{<br />&nbsp; &nbsp; float fw, fh;<br />&nbsp; &nbsp; if (ovalWidth == 0 || ovalHeight == 0) {<br />&nbsp; &nbsp; &nbsp; &nbsp; CGContextAddRect(context, rect);<br />&nbsp; &nbsp; &nbsp; &nbsp; return;<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; CGContextSaveGState(context);<br />&nbsp; &nbsp; CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));<br />&nbsp; &nbsp; CGContextScaleCTM (context, ovalWidth, ovalHeight);<br />&nbsp; &nbsp; fw = CGRectGetWidth (rect) / ovalWidth;<br />&nbsp; &nbsp; fh = CGRectGetHeight (rect) / ovalHeight;<br />&nbsp; &nbsp; CGContextMoveToPoint(context, fw, fh/2);<br />&nbsp; &nbsp; CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);<br />&nbsp; &nbsp; CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);<br />&nbsp; &nbsp; CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);<br />&nbsp; &nbsp; CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);<br />&nbsp; &nbsp; CGContextClosePath(context);<br />&nbsp; &nbsp; CGContextRestoreGState(context);<br />}<br /><br />+(UIImage *)makeRoundCornerImage : (UIImage*) img : (int) cornerWidth : (int) cornerHeight<br />{<br />	UIImage * newImage = nil;<br />	<br />	if( nil != img)<br />	{<br />		NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];<br />		int w = img.size.width;<br />		int h = img.size.height;<br />		<br />		CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();<br />		CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);<br />		<br />		CGContextBeginPath(context);<br />		CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);<br />		addRoundedRectToPath(context, rect, cornerWidth, cornerHeight);<br />		CGContextClosePath(context);<br />		CGContextClip(context);<br />		<br />		CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);<br />		<br />		CGImageRef imageMasked = CGBitmapContextCreateImage(context);<br />		CGContextRelease(context);<br />		CGColorSpaceRelease(colorSpace);<br />		[img release];<br />		<br />		newImage = [[UIImage imageWithCGImage:imageMasked] retain];<br />		CGImageRelease(imageMasked);<br />		<br />		[pool release];<br />	}<br />	<br />&nbsp; &nbsp; return newImage;<br />}<br />


Pour l'utiliser, tout d'abord importez le fichier .h :
#import &quot;ImageRoundedCorners.h&quot;


Et utilisez la méthode ainsi :
UIImage *monImage = [UIImage imageNamed:@&quot;image.png&quot;];<br />UIImage *imageArrondie = [ImageRoundedCorners makeRoundCornerImage: monImage :5 :5];


Où 5 est le radius de votre image, plus cette valeur est grande plus les coins seront arrondis.

Voilà , j'espère qu'elle vous servira, car il est vrai que sur certaines interfaces graphiques, les coins arrondis sur les image sont les bienvenus !

Réponses

  • Philippe49Philippe49 Membre
    08:56 modifié #2
    On pourrait ajouter un antialiasing dans ce code.

    Autre solution pour une UIImageView sans recréer d'image :
    <br />	CALayer * layer=imageView.layer;<br />	layer.cornerRadius=20.;<br />	layer.borderWidth=0.;<br />
    


    et pour matérialiser la bordure
    <br />	CALayer * layer=imageView.layer;<br />	layer.cornerRadius=20.;<br />	layer.borderWidth=5.;<br />	UIColor * borderColor=[UIColor colorWithRed:35.0/255. green:39./255. blue:101./255. alpha:1.];	<br />	layer.borderColor=borderColor.CGColor;<br />
    

  • remoozremooz Membre
    08:56 modifié #3
    Pratique cette astuce. Merci de la faire partager .  :kicking:
  • StephSteph Membre
    08:56 modifié #4
    Je viens d'essayer avec ce code (je suis dans mon tableView cellForRowAtIndexPath, je ferais autre chose après mais c'est pour tester) :

    CALayer *layerRound = cell.articleLogo.layer;<br />	layerRound.cornerRadius=20.;<br />	layerRound.borderWidth=5.;<br />	UIColor * borderColor=[UIColor colorWithRed:35.0/255. green:39./255. blue:101./255. alpha:1.];	<br />	layerRound.borderColor=borderColor.CGColor;<br />	<br />	cell.articleLogo.image = articleForRow.logo;
    


    J'ai bien la bordure, mais l'image reste carré, du coup ben elle dépasse du bord.

    Ah oui et il faut importer #import <QuartzCore/QuartzCore.h> pour que ça marche :)

    Une idée de pourquoi ça marche pas ?

    Merci :)

  • AliGatorAliGator Membre, Modérateur
    08:56 modifié #5
    faut passer la propriété clipSublayers à  YES sinon ça fait pas le clipping des sous-vues
  • StephSteph Membre
    08:56 modifié #6
    Ah !

    Je vais regarder ça ce soir, je ne suis pas devant mon mac. Mais la doc ne trouve rien sur cette propriété :(
  • AliGatorAliGator Membre, Modérateur
    08:56 modifié #7
    Désolé j'ai cité la propriété de mémoire, en fait elle s'appelle masksToBounds
    If YES, an implicit mask matching the layer bounds is applied to the layer, including the effects of the cornerRadius property. If YES and a mask property is specified, the two masks are multiplied to get the actual mask values. Defaults to NO.
  • StephSteph Membre
    janvier 2010 modifié #8
    Ah ben si tu m'enduis d'erreur lol

    Je regarde ça en rentrant du taf, merci :)

    Edit : En regardant un peu la doc, ça devrait fonctionner avec un

    [layerRound setMasksToBounds:YES];

    ou un

    layerRound.masksToBounds = YES;

    Je vous tiens au jus :)
  • StephSteph Membre
    08:56 modifié #9
    ça marche nickel :)

    Merci Ali 
Connectez-vous ou Inscrivez-vous pour répondre.