Hmmm ...
je manquer quelque chose, mais je ne crois pas que les réponses fournies appliquent à la question. La deuxième réponse se rapproche de la marque, mais elle contient un code erroné qui a peu à voir avec la solution.
La méthode createMask
fait une copie de l'image originale en supposant alpha en position LSB. ChangeColor effectue un appel de masquage qui ne va pas faire beaucoup à une image RVB - en fait, seul le noir va être masqué (c'est-à-dire, triplets RGB dans la gamme/combinaisons de (1,1,2) à (3, 2,1)).
Je suppose que le décalage vers le rouge qui est observée est due au paramètre
kCGImageAlphaPremultipliedFirst
dans la ligne
CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4, colorSpaceRef, kCGImageAlphaPremultipliedFirst);
en raison d'un mauvais traitement de la couche alpha. Si la méthode changeColor
vous modifiez le bloc
CGImageRef ref1=[self createMask:temp23];
const float colorMasking[6] = {1.0, 3.0, 1.0, 2.0, 2.0, 3.0};
CGImageRef New=CGImageCreateWithMaskingColors(ref1, colorMasking);
UIImage *resultedimage=[UIImage imageWithCGImage:New];
EditImageView.image = resultedimage;
être
CGImageRef ref1=[self createMask:temp23];
UIImage *resultedimage=[UIImage imageWithCGImage:ref];
EditImageView.image = resultedimage;
vous verrez aucune différence dans l'affichage. La modification de la constante CGBitmapInfo en kCGImageAlphaPremultipliedLast
doit afficher l'image correctement en utilisant l'un des blocs de code ci-dessus.
La réponse suivante se rapproche un peu plus de ce que l'OP demande, mais c'est en termes d'effet visuel, pas de données réelles. Voici le code pertinent dans createMask
est
CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4,colorSpaceRef, kCGImageAlphaPremultipliedLast);
qui affiche l'image correctement, suivie par
CGContextSetBlendMode(cgctx, kCGBlendModeColor);
CGContextSetRGBFillColor (cgctx, 1.0, 0.0, 0.0, 1.0);
CGContextFillRect(cgctx, rect);
et la logique pour la construction de l'image.La logique de fusion recouvre une teinte rouge sur l'image originale, obtenant un effet similaire à celui du canal alpha égaré dans la réponse d'origine. Ce n'est toujours pas ce que l'OP demande, c'est-à-dire masquer un ou plusieurs canaux, pas mélanger les couleurs.
Cela revient à régler les valeurs de canal pour les couleurs qui ne sont pas souhaitées à zéro. Voici un exemple pour renvoyer juste le canal rouge comme les demandes OP; l'hypothèse est que le format du pixel est ABGR:
- (CGImageRef) redChannel:(CGImageRef)image
{
CGDataProviderRef provider = CGImageGetDataProvider(image);
NSMutableData* data = (id)CGDataProviderCopyData(provider);
int width = CGImageGetWidth(image);
int height = CGImageGetHeight(image);
[data autorelease];
// get a mutable reference to the image data
uint32_t* dwords = [data mutableBytes];
for (size_t idx = 0; idx < width*height; idx++) {
uint32_t* pixel = &dwords[idx];
// perform a logical AND of the pixel with a mask that zeroes out green and blue pixels
*pixel &= 0x000000ff;
}
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
// now create a new image using the masked original data
CGDataProviderRef iprovider = CGDataProviderCreateWithData(NULL, dwords, width*height*4, NULL);
CGImageRef savedimageref = CGImageCreate(width, height, 8, 32, width*4, colorSpaceRef, bitmapInfo, iprovider, NULL, NO, renderingIntent);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(iprovider);
return savedimageref;
}
Un bon résumé des opérations binaires se trouve here.
Comme indiqué here, vous devrez peut-être modifier la structure du masque en fonction de l'ordre LSB/MSB des bits dans le pixel. Cet exemple suppose des pixels de 32 bits à partir d'un PNG iPhone standard.