Convertir UIImage en CVImageBufferRef

Ce code fonctionne principalement, mais datatables résultantes semblent perdre un canal de couleur (c'est ce que je pense) que datatables d'image résultantes lors de l'affichage est teinté en bleu!

Voici le code:

UIImage* myImage=[UIImage imageNamed:@"sample1.png"]; CGImageRef imageRef=[myImage CGImage]; CVImageBufferRef pixelBuffer = [self pixelBufferFromCGImage:imageRef]; 

La méthode pixelBufferFromCGIImage a été récupérée à partir d'un autre article sur stackoverflow ici: Comment exporter un tableau UIImage en tant que film? (bien que cette application est sans rapport avec ce que j'essaie de faire), il est

 + (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image { CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image)); NSDictionary *options = @{ (__bridge NSSsortingng *)kCVPixelBufferCGImageCompatibilityKey: @(NO), (__bridge NSSsortingng *)kCVPixelBufferCGBitmapContextCompatibilityKey: @(NO) }; CVPixelBufferRef pixelBuffer; CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width, frameSize.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options, &pixelBuffer); if (status != kCVReturnSuccess) { return NULL; } CVPixelBufferLockBaseAddress(pixelBuffer, 0); void *data = CVPixelBufferGetBaseAddress(pixelBuffer); CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(data, frameSize.width, frameSize.height, 8, CVPixelBufferGetBytesPerRow(pixelBuffer), rgbColorSpace, (CGBitmapInfo) kCGImageAlphaNoneSkipLast); CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image); CGColorSpaceRelease(rgbColorSpace); CGContextRelease(context); CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); return pixelBuffer; } 

Je pense qu'il a quelque chose à voir avec la relation entre kCVPixelFormatType_32ARGB et kCGImageAlphaNoneSkipLast bien que j'ai essayé toutes les combinaisons et get le même résultat ou un plantage de l'application. Encore une fois, ceci obtient datatables de UIImage dans CVImageBufferRef mais quand j'affiche l'image à l'écran, il semble perdre un canal de couleur et montre le bleu teinté. L'image est un png.

On dirait que ça pourrait être cette relation. Peut-être avoir un jpg et RVB au lieu de colors indexées avec un png?

La solution est que ce code fonctionne parfaitement comme prévu. 🙂 Le problème était en utilisant datatables dans la création d'une texture OpenGL. Complètement sans rapport avec ce code. Toute personne cherchant comment convertir UIImage en CVImageBufferRef, votre réponse est dans le code ci-dessus!

Si quelqu'un cherche toujours une solution à ce problème, je l'ai résolu en changeant les BOOL dans les options du pixelBuffer:

 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:NO], kCVPixelBufferCGBitmapContextCompatibilityKey, nil]; 

De NO à YES:

 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil]; 

Je rencontre le même problème et trouve quelques exemples: http://www.cakesolutions.net/teamblogs/2014/03/08/cmsamplebufferref-from-cgimageref
Essayer de changer

 CGBitmapInfo bitmapInfo = (CGBitmapInfo)kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst) 

Voici ce qui fonctionne vraiment:

 + (CVPixelBufferRef)pixelBufferFromImage:(CGImageRef)image { CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image)); // Not sure why this is even necessary, using CGImageGetWidth/Height in status/context seems to work fine too CVPixelBufferRef pixelBuffer = NULL; CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width, frameSize.height, kCVPixelFormatType_32BGRA, nil, &pixelBuffer); if (status != kCVReturnSuccess) { return NULL; } CVPixelBufferLockBaseAddress(pixelBuffer, 0); void *data = CVPixelBufferGetBaseAddress(pixelBuffer); CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(data, frameSize.width, frameSize.height, 8, CVPixelBufferGetBytesPerRow(pixelBuffer), rgbColorSpace, (CGBitmapInfo) kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image); CGColorSpaceRelease(rgbColorSpace); CGContextRelease(context); CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); return pixelBuffer; } 

Vous pouvez changer le tampon de pixels en UIImage (puis l'afficher ou l'save) pour confirmer qu'il fonctionne avec cette méthode:

 + (UIImage *)imageFromPixelBuffer:(CVPixelBufferRef)pixelBuffer { CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer]; CIContext *context = [CIContext contextWithOptions:nil]; CGImageRef myImage = [context createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer))]; UIImage *image = [UIImage imageWithCGImage:myImage]; // Uncomment the following lines to say the image to your application's document directory //NSSsortingng *imageSavePath = [documentsDirectory ssortingngByAppendingPathComponent:[NSSsortingng ssortingngWithFormat:@"myImageFromPixelBuffer.png"]]; //[UIImagePNGRepresentation(image) writeToFile:imageSavePath atomically:YES]; return image; } 

Juste pour clarifier la réponse ci-dessus: j'ai rencontré le même problème parce que mon code shader attendait deux échantillons en couches dans un tampon d'image, alors que j'ai utilisé un tampon de couche unique

Cette ligne a pris les valeurs rgb d'un échantillon et les a transmises (je ne sais pas quoi), mais le résultat final est une image pleine couleur.

  gl_FragColor = vec4(texture2D(SamplerY, texCoordVarying).rgb, 1);