Comment replace une couleur donnée par une autre sur un UIImage opaque

Je veux changer la couleur d'un UIImage opaque. Mon image originale est la suivante:

entrez la description de l'image ici

et je veux convertir l'image au format suivant

entrez la description de l'image ici

Donc, fondamentalement, je veux convertir la couleur rouge de l'image en couleur noire (toute autre couleur). Au-dessus de deux images sont ajoutées pour une meilleure compréhension.

Je ne pouvais pas voir de réponses sur les 'duplicates' (cette question ne devrait pas avoir été marquée comme doublon) qui vous permettra de replace une couleur donnée par une autre couleur et de travailler sur une image opaque, donc j'ai décidé d'en append une aurait.


J'ai créé une catégorie UIImage pour cela, elle fonctionne essentiellement en faisant une boucle sur chaque pixel et en détectant à quel point elle est proche d'une couleur donnée, et la mélange avec votre couleur de rlocation si c'est le cas.

Cela fonctionnera pour les images avec à la fois des fonds transparents et opaques .

 @implementation UIImage (UIImageColorReplacement) -(UIImage*) imageByReplacingColor:(UIColor*)sourceColor withMinTolerance:(CGFloat)minTolerance withMaxTolerance:(CGFloat)maxTolerance withColor:(UIColor*)destinationColor { // components of the source color const CGFloat* sourceComponents = CGColorGetComponents(sourceColor.CGColor); UInt8* source255Components = malloc(sizeof(UInt8)*4); for (int i = 0; i < 4; i++) source255Components[i] = (UInt8)round(sourceComponents[i]*255.0); // components of the destination color const CGFloat* destinationComponents = CGColorGetComponents(destinationColor.CGColor); UInt8* destination255Components = malloc(sizeof(UInt8)*4); for (int i = 0; i < 4; i++) destination255Components[i] = (UInt8)round(destinationComponents[i]*255.0); // raw image reference CGImageRef rawImage = self.CGImage; // image atsortingbutes size_t width = CGImageGetWidth(rawImage); size_t height = CGImageGetHeight(rawImage); CGRect rect = {CGPointZero, {width, height}}; // bitmap format size_t bitsPerComponent = 8; size_t bytesPerRow = width*4; CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big; // data pointer UInt8* data = calloc(bytesPerRow, height); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // create bitmap context CGContextRef ctx = CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); CGContextDrawImage(ctx, rect, rawImage); // loop through each pixel's components for (int byte = 0; byte < bytesPerRow*height; byte += 4) { UInt8 r = data[byte]; UInt8 g = data[byte+1]; UInt8 b = data[byte+2]; // delta components UInt8 dr = abs(r-source255Components[0]); UInt8 dg = abs(g-source255Components[1]); UInt8 db = abs(b-source255Components[2]); // ratio of 'how far away' each component is from the source color CGFloat ratio = (dr+dg+db)/(255.0*3.0); if (ratio > maxTolerance) ratio = 1; // if ratio is too far away, set it to max. if (ratio < minTolerance) ratio = 0; // if ratio isn't far enough away, set it to min. // blend color components data[byte] = (UInt8)round(ratio*r)+(UInt8)round((1.0-ratio)*destination255Components[0]); data[byte+1] = (UInt8)round(ratio*g)+(UInt8)round((1.0-ratio)*destination255Components[1]); data[byte+2] = (UInt8)round(ratio*b)+(UInt8)round((1.0-ratio)*destination255Components[2]); } // get image from context CGImageRef img = CGBitmapContextCreateImage(ctx); // clean up CGContextRelease(ctx); CGColorSpaceRelease(colorSpace); free(data); free(source255Components); free(destination255Components); UIImage* returnImage = [UIImage imageWithCGImage:img]; CGImageRelease(img); return returnImage; } @end 

Usage:

 UIImage* colaImage = [UIImage imageNamed:@"cola1.png"]; UIImage* blackColaImage = [colaImage imageByReplacingColor:[UIColor colorWithRed:1 green:0 blue:0 alpha:1] withMinTolerance:0.5 withMaxTolerance:0.6 withColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1]]; 

La minTolerance est le point auquel les pixels vont commencer à se fondre avec la couleur de rlocation (plutôt que d'être remplacée). La maxTolerance est le point auquel les pixels cesseront d'être mélangés.

Avant:

entrez la description de l'image ici

Après:

entrez la description de l'image ici

Le résultat est un peu aliasé, mais gardez à l'esprit que votre image originale était assez petite. Cela fonctionnera beaucoup mieux avec une image à plus haute résolution. Vous pouvez également jouer avec les tolérances pour get des résultats encore meilleurs!

Vous pouvez utiliser ceci

  theImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [theImageView setTintColor:[UIColor blackColor]]; 

Je pense que quelque chose ne va pas avec votre image ici est mon image, elle est en blanc. entrez la description de l'image ici

voici le changement de simulateur entrez la description de l'image ici

Remarque: Tout d'abord, vous devez définir l'arrière-plan de votre image comme transparent avec Photoshop ou tout autre outil.

Ensuite, utilisez le code ci-dessous.

Facile, vous devez utiliser le mode de rendu pour changer cette couleur.

 cokeImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; // yourimageviewname [cokeImageView setTintColor:[UIColor blackColor]];