UIImage et Image negative

LastikoLastiko Membre
10:14 modifié dans API UIKit #1
bonsoir a tous ,

je me pose une petite question , est il possible d'inversé une image , j'entends inversé par faire comme la fonction Negatif dans photoshop qui donne donc une image negative , j'aimerai beaucoup le faire dans mon projets qui utilise UIImage

Si quelqu'un a la bonté de m'eclairer

merci par avance

Lastiko

Réponses

  • AliGatorAliGator Membre, Modérateur
    10:14 modifié #2
    Salut Lastiko,

    Le plus simple est de dessiner ton image en utilisant le mode "DifferenceBlendMode" ou éventuellement ExclusionBlendMode.

    Soit tu dessines ton image avec ce mode de rendu sur un fond blanc dans ta vue (avec la méthode [tt]drawAtPoint:blendMode:alpha:[/tt] de UIImage par exemple), soit tu dessines ton image avec ce mode dans une image intermédiaire toute blanche, pour avoir cette image inversée en mémoire, et tu dessines cette image intermédiaire inversée ensuite.
  • LastikoLastiko Membre
    10:14 modifié #3
    dans 1229970565:

    Salut Lastiko,

    Le plus simple est de dessiner ton image en utilisant le mode "DifferenceBlendMode" ou éventuellement ExclusionBlendMode.

    Soit tu dessines ton image avec ce mode de rendu sur un fond blanc dans ta vue (avec la méthode [tt]drawAtPoint:blendMode:alpha:[/tt] de UIImage par exemple), soit tu dessines ton image avec ce mode dans une image intermédiaire toute blanche, pour avoir cette image inversée en mémoire, et tu dessines cette image intermédiaire inversée ensuite.



    Merci beaucoup pour ta réponse Aligator :D
  • AliGatorAliGator Membre, Modérateur
    décembre 2008 modifié #4
    Bon je te répond ici même si tu m'as mis un message perso... car je ne vois pas l'intérêt de continuer la conversation en public fermé là  où tous les membres du forum peuvent aider, je n'ai pas réponse à  tout et après tout c'est le principe même des forums ;)

    Alors puisque comme tu me le mettais dans ton MP tu veux affecter cette image à  une UIImageView avec maview.image = ..., il faut au préalable créer ton image "inversée" (en négatif) dans une UIImage temporaire.

    Après, pour les fonctions, c'est indiqué ici dans la doc.

    Au feeling (la flemme de lancer Xcode pour checker) ça devrait donc donner un truc du genre :
    UIImage* origImage = [[UIImage alloc] initWithData: [NSData dataWithContentsOfURL:urldownload]];<br /><br />UIGraphicsBeginImageContext( origImage.size ); // créer un contexte graphique pour dessiner l&#39;image inversée<br /><br />&nbsp; &nbsp; // on dessine l&#39;image avec le blendMode adéquat pour inverser<br />[origImage drawAtPoint:CGPointMake(0,0) blendMode:kCGBlendModeDifference alpha:1.0]; <br />&nbsp; &nbsp; // récupérer l&#39;image inversée, et l&#39;affecter à  ta UIImageView<br />imageGrenouille.image = UIGraphicsGetImageFromCurrentImageContext();<br /><br />UIGraphicsEndImageContext(); // fin de la création de l&#39;image inversée<br /><br />[origImage release]; // on peut aussi relâcher l&#39;image originelle
    
    A tester pour vérifier mais tu vois l'idée.
  • LastikoLastiko Membre
    10:14 modifié #5
    Merci Aligator ,

    il est vrai que je t'ai fais un MP car je me suis dis que j'allais pas déranger tout le monde avec mon probleme :D

    je test ton code demain , on verra si je patoge moins avec ca  , c'est d'ailleur maintenant ce qui manque a ma premiere appli

    Merci beaucoup a toi et aux autres d'ailleurs car c'est la mine d'or ici , enfin a mon gout :P

    +
    J.
  • LastikoLastiko Membre
    10:14 modifié #6
    Bon alors j'ai essayer sans succes enfin si ca affiche bien une image mais identique a celle d'origine
    j'ai donc créé une autre image pour etre sur et meme resultat , j'ai tester aussi avec le mode Exclusion et ca change rien
    :(

    grrrrr vilaine image :D

  • AliGatorAliGator Membre, Modérateur
    décembre 2008 modifié #7
    Ah oui je viens de vérifier par le code, en fait c'est parce que la couleur par défaut est noir.
    Du coup quand tu crées le GraphicContext temporaire pour dessiner ton image inversée dedans... ben au moment où elle est créée, elle est toute noire, et pas toute blanche ! (et du coup dessiner avec le mode Difference (ou Exclusion) ne change pas l'image d'origine)

    Le plus simple est donc de dessiner un rectangle blanc après la création de ce contexte : donc écrire ces deux lignes après le [tt] UIGraphicsBeginImageContext(...)[tt] :
    CGContextSetRGBFillColor(UIGraphicsGetCurrentContext(), 1.0, 1.0, 1.0, 1.0); // choisir la couleur blanche<br />UIRectFill(origImage.size); // remplir un rectangle de cette couleur
    
    Et après tu dessines comme avant ton image, avec le mode "difference", et ça marche (testé).
  • AliGatorAliGator Membre, Modérateur
    décembre 2008 modifié #8
    Code complet (que j'ai mis dans une IBAction pour tester, comme ça ça charge l'image quand je clique sur un bouton, mais tu peux la mettre dans ton viewDidLoad ou autre part bien sûr) :
    - (IBAction)loadNegativeImage:(id)sender {<br />	NSURL* urldownload = [NSURL URLWithString:@&quot;http://www.slashon.com/upload/image/apple.png&quot;];<br />	UIImage* origImage = [[UIImage alloc] initWithData: [NSData dataWithContentsOfURL:urldownload]];<br /><br />	// récupérer la taille de l&#39;image d&#39;origine (pour utiliser pour la taille de destination)<br />	CGSize destSize = CGSizeMake(origImage.size.width/4, origImage.size.height/4); // j&#39;en profite pour la diviser par 4<br />	CGRect destRect = CGRectMake(0,0,destSize.width, destSize.height);<br /><br />	UIGraphicsBeginImageContext( destSize ); // créer un contexte graphique pour dessiner l&#39;image inversée<br />	<br />	// on remplis l&#39;image (le contexte graphique créé au dessus) par du blanc<br />	CGContextSetRGBFillColor(UIGraphicsGetCurrentContext(), 1.0, 1.0, 1.0, 1.0); <br />	UIRectFill(destRect);<br />	// puis on dessine l&#39;image avec le blendMode adéquat pour inverser<br />	[origImage drawInRect:destRect blendMode:kCGBlendModeDifference alpha:1.0]; <br />	// récupérer enfin l&#39;image inversée, et l&#39;affecter à  ta UIImageView<br />	imageGrenouille.image = UIGraphicsGetImageFromCurrentImageContext();<br />	<br />	UIGraphicsEndImageContext(); // on en a fini avec la création de l&#39;image inversée<br />	<br />	[origImage release]; // on peut aussi relâcher l&#39;image originelle dont on n&#39;a plus besoin<br />}<br />
    


    PS : Attention je n'ai pas vérifié mais avec cette méthode tu risques de perdre la transparence de ton image (puisqu'on dessine l'image, avec le blendmode "difference", ... sur une image remplie de blanc -- donc opaque --> l'image ainsi créée gardera donc le blanc opaque du fond là  où ton image était transparente). Si cela te pose un réel problème, il faudrait alors idéalement réappliquer le masque (canal alpha / transparence) de ton image d'origine sur l'image inversée ainsi créée (j'ai pas encore regardé comment faire pour ça).
  • LastikoLastiko Membre
    10:14 modifié #9
    Mon Dieu :P

    ca marche et effectivement ca perd la transparance , mais ca inverse :P
  • AliGatorAliGator Membre, Modérateur
    décembre 2008 modifié #10
    Pour appliquer la transparence, il suffit de redessiner l'image avec le blendmode "DestinationIn" qui applique comme formule comme le dit la doc : "R = D*Sa", autrement dit ça multiple la destination (contenu actuel de ton image en cours de dessin) par la couche alpha de l'image source (ton "origImage") : donc ça "applique la couche alpha de origImage" sur ton image en cours de dessin (ton graphic context).

    // on remplit l&#39;image (le contexte graphique créé au dessus) par du blanc<br />CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), [[UIColor whiteColor] CGColor]); <br />UIRectFill(destRect);<br />// puis on dessine l&#39;image avec le blendMode &quot;difference&quot; pour inverser<br />[origImage drawInRect:destRect blendMode:kCGBlendModeDifference alpha:1.0];<br />// on redessine avec le mode &quot;destinationIn&quot; (R = D*Sa) pour réappliquer l&#39;alpha de origImage (Sa)<br />[origImage drawInRect:destRect blendMode:kCGBlendModeDestinationIn alpha:1.0];<br />
    
  • LastikoLastiko Membre
    10:14 modifié #11
    Et je Confirme que ca marche parfaitement

    UN GRAND MERCI  ALIgator :P
  • AliGatorAliGator Membre, Modérateur
    10:14 modifié #12
    Comme je suis un perfectionniste, je peaufine en livrant le code final, en mettant le code d'inversion d'image à  part... Oh, bof, en fait, pas assez peaufiné... allez quitte à  faire classe, on va même faire une catégorie sur UIImage tant qu'on y est, zou !  :)

    Donc la catégorie de UIImage, pour rajouter la méthode "negative" à  la classe UIImage, ça donne ça (à  mettre dans un .h séparé... voire dans ton .h principal où tu veux utiliser cette méthode (moins joli mais bon), et tu peux faire un .m aussi pour le @implementation mais moi pour si peu je met tout dans le .h en général :o )
    @interface UIImage(Negative)<br />-(UIImage*)negative;<br />@end<br /><br />@implementation UIImage(Negative)<br />-(UIImage*)negative {<br />	UIGraphicsBeginImageContext( self.size ); // créer un contexte graphique pour dessiner l&#39;image inversée<br />	CGRect destRect = CGRectMake(0,0,self.size.width, self.size.height);<br />	<br />	// on remplit l&#39;image (le contexte graphique créé au dessus) par du blanc<br />	CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), [[UIColor whiteColor] CGColor]); <br />	UIRectFill(destRect);<br />	<br />	// puis on dessine l&#39;image avec le blendMode &quot;difference&quot; pour inverser<br />	[self drawInRect:destRect blendMode:kCGBlendModeDifference alpha:1.0];<br />	// on redessine avec le mode &quot;destinationIn&quot; (R = D*Sa) pour réappliquer l&#39;alpha de origImage (Sa)<br />	[self drawInRect:destRect blendMode:kCGBlendModeDestinationIn alpha:1.0];<br />	<br />	// récupérer enfin l&#39;image inversée, et l&#39;affecter à  ta UIImageView<br />	UIImage* invertedImage = UIGraphicsGetImageFromCurrentImageContext();<br />	UIGraphicsEndImageContext(); // on en a fini avec la création de l&#39;image inversée<br />	<br />	return invertedImage;<br />}<br />@end
    
    Et en imaginant qu'on a un UISwitch "invertSwitch" dans notre interface pour choisir si on veut l'image normale ou en "négatif", l'IBAction devient :
    - (IBAction)loadImage:(id)sender {<br />	NSURL* urldownload = [NSURL URLWithString:@&quot;http://www.hotpng.com/attach-diy/images/PNG_transparency_demonstration_1.png&quot;];<br />	UIImage* origImage = [[UIImage alloc] initWithData: [NSData dataWithContentsOfURL:urldownload]];<br />	<br />	imageGrenouille.image = invertSwitch.on ? [origImage negative] : origImage;<br /><br />	[origImage release]; // on peut aussi relâcher l&#39;image originelle dont on n&#39;a plus besoin<br />}
    

  • LastikoLastiko Membre
    10:14 modifié #13
    moi je dis ce post doit etre mis en resolut car y a tous fourni par aliGator et ca marche , confirmé certifier et fonctionnel :P

    un Grand merci et résolu
  • LastikoLastiko Membre
    10:14 modifié #14
    est ce que quelqu'un sait comment on ajoute cette image a une autre image et qu'on enregistre tout ca comme une seule ??

    je sais pas si je suis trés clair la

    en faite cette image negative si je veux lui ajouter par exemple ben je vous le donne en mile un bord comme une pellicule par exemple
    et que cela me donne une seul image negative avec un aspect de péllicule photo

    Merci par avance pour les eventuelles réponses

    Lastiko
  • AliGatorAliGator Membre, Modérateur
    10:14 modifié #15
    Ben heu même principe ;)

    - [tt]UIGraphicsBeginImageContext(taille)[/tt] pour créer un contexte graphique te permettant de "créer"/composer ton image
    - ensuite tu dessines l'image 1 puis l'image 2 puis tout ce que tu veux dessiner sur ton image finale, etc (avec des appels à  "drawInRect" de la classe UIImage pour dessiner des images, UIRectFill et UIRectFrame pour dessiner des rectangles pleins ou juste le bord d'un rectangle, etc
    - Une fois que tu as terminé tes opérations de dessin (dessiner ton image, puis l'autre, sur ton contexte graphique de composition), tu récupères l'image ainsi produite avec [tt]UIImage* composedImage = UIGraphicsGetImageFromCurrentImageContext();[/tt], puis tu indiques que tu en as fini avec le contexte graphique de composition avec [tt]UIGraphicsEndImageContext()[/tt]

    Et voilà , dans composedImage tu as alors une UIImage correspondant à  ton image telle que tu l'as composée, donc correspondant à  ce que tu as dessiné entre [tt]UIGraphicsBeginImageContext[/tt] et [tt]UIGraphicsEndImageContext[/tt].
  • LastikoLastiko Membre
    10:14 modifié #16
    si simplement et moi qui me disait non doit y avoir un autre truc  ;D

    comme quoi faut pas chercher compliqué des fois  :o
Connectez-vous ou Inscrivez-vous pour répondre.