2010-07-29 14 views
5

Estoy tratando de recuperar los datos de imagen de una uiimage, modificarla y crear una nueva uiimage a partir de ella. Para empezar, intenté simplemente copiar los datos sin ninguna modificación para obtener los conceptos básicos, pero eso falla (UIImage +imageWithData: devuelve nada). ¿Alguien puede ver por qué esto no funcionaría?Creando un UIImage de otro UIImage usando imageWithData devuelve nil

// I've confirmed that the follow line works 

UIImage *image = [UIImage imageNamed:@"image_foo.png"]; 

// Get a reference to the data, appears to work 

CFDataRef dataRef = CGDataProviderCopyData(CGImageGetDataProvider([image CGImage])); 

// Get the length of memory to allocate, seems to work (e.g. 190000) 

int length = CFDataGetLength(dataRef) * sizeof(UInt8); 

UInt8 * buff = malloc(length); 

// Again, appears to work 

CFDataGetBytes(dataRef, CFRangeMake(0,length),buff); 

// Again, appears to work 

NSData * newData = [NSData dataWithBytesNoCopy:buff length:length]; 

// This fails by returning nil 

UIImage *image2 = [UIImage imageWithData:newData]; 

Nota:

También probé usando:

uint8 * = datos CFDataGetBytePtr (dataRef);

y solo conectando directamente a NSData.

Mismo resultado.

+1

¿Por qué dataWithBytesNoCopy? – jsicary

+0

se usó dataWithBytesNoCopy porque él mismo asignó el búfer utilizando malloc. De esta forma, tendrá acceso al búfer de imagen real de image2 durante toda la vida útil de ese objeto. – Till

Respuesta

1

Creo que imageWithData toma image-file-data, no image-display-data, que es lo que le está pasando. Intentar algo como esto:

NSData * newData = UIImageJPEGRepresentation(image, 1.0); 
UIImage *image2 = [UIImage imageWithData:newData]; 

UIImageJPegRepresentation() devuelve los datos que podría escribir en un archivo para crear un archivo .jpg en el disco. Eso, estoy 99.44% seguro es lo que imageWithData: quiere.

NOTA: si está buscando manipular los datos antes de crear image2, entonces do quiere los datos de visualización, en cuyo caso la forma en que obtiene una imagen de eso es un poco más complicada, pero se ve algo de esta manera:

// Create a color space 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    if (colorSpace == NULL) 
    { 
     fprintf(stderr, "Error allocating color space\n"); 
     return nil; 
    } 

    CGContextRef context = CGBitmapContextCreate (bits, size.width, size.height, 
      8, size.width * 4, colorSpace, 
      kCGImageAlphaPremultipliedLast | IMAGE_BYTE_ORDER 
      ); 
    CGColorSpaceRelease(colorSpace); 

    if (context == NULL) 
    { 
     fprintf (stderr, "Error: Context not created!"); 
     return nil; 
    } 

    CGImageRef ref = CGBitmapContextCreateImage(context); 
    //free(CGBitmapContextGetData(context));          //* this appears to free bits -- probably not mine to free! 
    CGContextRelease(context); 

    UIImage *img = [UIImage imageWithCGImage:ref]; 
    CFRelease(ref);                //* ?!?! Bug in 3.0 simulator. Run in 3.1 or higher. 

    return img; 

(... el código anterior se deriva de ejemplos por Erica Sadun las piezas inteligentes son de ella; los errores son todos míos pero esta es la idea general, y debería funcionar)