2010-07-29 8 views
5

Je suis en train de récupérer les données d'image d'un UIImage, modifier et créer une nouvelle UIImage de celui-ci. Pour commencer, j'ai essayé de copier les données sans aucune modification pour obtenir les bases, mais cela échoue (UIImage +imageWithData: renvoie zéro). Quelqu'un peut-il voir pourquoi cela ne fonctionnerait pas?Création d'un UIImage d'un autre UIImage utilisant imageWithData renvoie 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]; 

Note:

J'ai aussi essayé d'utiliser:

UInt8 * data = CFDataGetBytePtr (dataref);

et juste de canaliser directement dans NSData.

Même résultat.

+1

pourquoi dataWithBytesNoCopy? – jsicary

+0

dataWithBytesNoCopy a été utilisé car il a alloué lui-même le tampon en utilisant malloc. De cette façon, il aura accès à l'image tampon réelle de l'image2 pendant toute la durée de vie de cet objet. – Till

Répondre

1

Je crois que imageWithData prend image-fichier-données, pas image-affichage-données, qui est ce que vous le transmettez. Essayez quelque chose comme ceci:

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

UIImageJPegRepresentation() renvoie les données que vous écrire dans un fichier pour créer un fichier .jpg sur le disque. Cela, je suis 99,44% sûr est ce que veut imageWithData:.

REMARQUE: si vous cherchez à manipuler les données avant de créer image2, vous ne veulent que les données d'affichage, dans ce cas, la façon dont vous obtenez une image en arrière de ce qui est un peu plus compliqué, mais ressemble à quelque chose comme ceci:

// 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; 

(... le code ci-dessus provient d'exemples par Erica Sadun les parties intelligentes sont les siennes, les erreurs sont tout à moi mais c'est l'idée générale, et il devrait fonctionner)