Quiero convertir un UIImage objeto a un CVPixelBufferRef objeto, pero tengo absolutamente ni idea. Y yo no se puede encontrar ningún ejemplo de código haciendo algo como esto.

Por favor alguien puede ayudarme? THX de antemano!

C YA

InformationsquelleAutor Nuker | 2010-10-01

5 Comentarios

  1. 7

    Hay diferentes maneras de hacerlo, esas funciones convertir un pixel buffer de un CGImage. UImage es un contenedor CGImage, por lo tanto para obtener un CGImage sólo necesita llamar al método .CGImage.

    Las otras formas son también crear un CIImage del búfer (ya publicado) o el uso de la Accelerate marco, que es probablemente la más rápida pero también la más difícil.

    - (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
    {
    NSDictionary *options = @{
    (NSString*)kCVPixelBufferCGImageCompatibilityKey : @YES,
    (NSString*)kCVPixelBufferCGBitmapContextCompatibilityKey : @YES,
    };
    CVPixelBufferRef pxbuffer = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image),
    CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options,
    &pxbuffer);
    if (status!=kCVReturnSuccess) {
    NSLog(@"Operation failed");
    }
    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(image),
    CGImageGetHeight(image), 8, 4*CGImageGetWidth(image), rgbColorSpace,
    kCGImageAlphaNoneSkipFirst);
    NSParameterAssert(context);
    CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
    CGAffineTransform flipVertical = CGAffineTransformMake( 1, 0, 0, -1, 0, CGImageGetHeight(image) );
    CGContextConcatCTM(context, flipVertical);
    CGAffineTransform flipHorizontal = CGAffineTransformMake( -1.0, 0.0, 0.0, 1.0, CGImageGetWidth(image), 0.0 );
    CGContextConcatCTM(context, flipHorizontal);
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
    CGImageGetHeight(image)), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);
    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
    return pxbuffer;
    }
    • ¿por qué iba a voltear vertical y horizontal?
    • Porque UIKit y el núcleo grphics tienen diferentes sistemas de coordenadas developer.apple.com/library/content/documentation/2DDrawing/…
    • La coordenada y sí, pero no el x… ?
    • Hola he usado el código y me estoy poniendo accidente :- 2019-03-19 12:08:01.233465+0530 YoPlay[3693:866159] *** Terminación de la aplicación debido a uncaught exception ‘NSInternalInconsistencyException’, la razón: ‘parámetro no Válido no satisfactorio: status == kCVReturnSuccess && pxbuffer != NULL’ puede usted por favor me ayude con esto?
  2. 2

    Puede utilizar la Imagen principal para crear un CVPixelBuffer de un UIImage.

    //1. Create a CIImage with the underlying CGImage encapsulated by the UIImage (referred to as 'image'):
    CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage];
    //2. Create a CIContext:
    Context *ciContext = [CIContext contextWithCGContext:UIGraphicsGetCurrentContext() options:nil];
    //3. Render the CIImage to a CVPixelBuffer (referred to as 'outputBuffer'):
    [self.ciContext render:img toCVPixelBuffer:outputBuffer];

    AVFoundation proporciona clases que leer archivos de video (llamados activos) y de la salida de otras AVFoundation objetos que manejan (o ya han leído) activos en píxeles de los buffers. Si esa es su única preocupación, usted encontrará lo que usted está buscando en el Ejemplo de Edición de Fotos Extensión de código de ejemplo.

    Si su fuente se genera a partir de una serie de UIImage objetos (tal vez no habrá ningún archivo de origen, y se crea un nuevo archivo de contenido generado por el usuario), luego el código de ejemplo proporcionado anteriormente será suficiente.

    NOTA: no es el medio más eficiente ni el único medio para convertir un UIImage en un CVPixelBuffer; pero, es, con MUCHO, el medio más fácil. El uso de Gráficos de Núcleo para convertir un UIImage en un CVPixelBuffer requiere de mucho más código para configurar los atributos, tales como pixel buffer de tamaño y espacio de color, que la Imagen principal toma el cuidado de usted.

    • No estoy seguro de lo que está causando esto. Pero CIContext creación se produce un error en un multi-threaded contexto. Lo extraño es que esto sólo sucede cuando estoy procesamiento de las imágenes rápidamente. Cuando lo hago poco a poco, este no parece ser un problema.
    • Yo no tengo ningún problema, pero he aprendido todo, en-y-outs de cada imagen-marco del procesamiento de datos disponible para iOS. Yo tendría que ver el código para las uñas hacia abajo para asegurarse, pero aquí es algo a tratar: crear una sola instancia de CIContext a reutilizar para cada imagen; y, asegúrese de que usted está creando el contexto adecuado. Cada uno son muy diferentes; y, mientras que el compilador puede dejar de crear cualquiera de ellos, no todos ellos funcionan en todos los casos. La documentación está bien-mejora; consultar para más.
  3. 1

    De Google siempre es tu amigo. La búsqueda para «CVPixelBufferRef» el primer resultado conduce a este fragmento de snipplr:

    - (CVPixelBufferRef)fastImageFromNSImage:(NSImage *)image{
    CVPixelBufferRef buffer = NULL;
    //config
    size_t width = [image size].width;
    size_t height = [image size].height;
    size_t bitsPerComponent = 8; //*not* CGImageGetBitsPerComponent(image);
    CGColorSpaceRef cs = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    CGBitmapInfo bi = kCGImageAlphaNoneSkipFirst; //*not* CGImageGetBitmapInfo(image);
    NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
    //create pixel buffer
    CVPixelBufferCreate(kCFAllocatorDefault, width, height, k32ARGBPixelFormat, (CFDictionaryRef)d, &buffer);
    CVPixelBufferLockBaseAddress(buffer, 0);
    void *rasterData = CVPixelBufferGetBaseAddress(buffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(buffer);
    //context to draw in, set to pixel buffer's address
    CGContextRef ctxt = CGBitmapContextCreate(rasterData, width, height, bitsPerComponent, bytesPerRow, cs, bi);
    if(ctxt == NULL){
    NSLog(@"could not create context");
    return NULL;
    }
    //draw
    NSGraphicsContext *nsctxt = [NSGraphicsContext graphicsContextWithGraphicsPort:ctxt flipped:NO];
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:nsctxt];
    [image compositeToPoint:NSMakePoint(0.0, 0.0) operation:NSCompositeCopy];
    [NSGraphicsContext restoreGraphicsState];
    CVPixelBufferUnlockBaseAddress(buffer, 0);
    CFRelease(ctxt);
    return buffer;
    }

    Ni idea de si esto funciona en todos, sin embargo. (Su kilometraje puede desconfiar 🙂

    • La pregunta era acerca de la conversión de un UIImage a CVPixelBufferRef, no NSImage
    • La línea sobre size_t bytesPerRow = CVPixelBufferGetBytesPerRow(buffer); es lo que hizo el truco para mí. Todos los demás ejemplos de código mediante un mágico constante que pasa a estar mal en este dispositivo, de ser capaz de determinar el valor real era la clave. Gracias.
  4. 0

    Un CVPixelBufferRef es lo básico de vídeo se utiliza para la entrada de la cámara.

    Puede crear similar píxeles de mapas de bits a partir de imágenes utilizando CGBitmapContextCreate y luego dibujar la imagen en el contexto de mapa de bits.

    • Lo que quiero hacer es añadir fotogramas de una película utilizando la AV de la Fundación. Esto se hará uso de la clase AVAssetWriterInputPixelBufferAdaptor. Pero esta clase se espera que CVPixelBufferRef objetos. Así que, ¿cómo puedo convertir de un UIImage a un CVPixelBufferRef objeto?
  5. 0

    Muy tarde, pero para alguien que lo necesita.

     //call like this
    CVPixelBufferRef videobuffer = [self pixelBufferFromCGImage:yourImage.CGImage]; 

    //método que convierte

    -(CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image{
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
    [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
    CVPixelBufferRef pxbuffer = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, videoSize.width, videoSize.height,
    kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef)options, &pxbuffer);
    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
    NSParameterAssert(pxdata != NULL);
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, videoSize.width, videoSize.height, 8, 4*videoSize.width, rgbColorSpace, kCGImageAlphaNoneSkipFirst);
    NSParameterAssert(context);
    CGContextConcatCTM(context, CGAffineTransformIdentity);
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);
    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
    return pxbuffer;
    }
    • He intentado esto. El uso de este la imagen de marco se recorta. Así que aquí está la solución CGContextDrawImage(contexto, CGRectMake(0, 0, videoSize.ancho, videoSize.altura), imagen);

Dejar respuesta

Please enter your comment!
Please enter your name here