2010-07-29 12 views
5

Ich versuche, die Bilddaten von einem uiimage abrufen, ändern, und erstellen Sie ein neues uiimage von ihm. Um zu beginnen, habe ich versucht, nur die Daten ohne irgendeine Änderung zu kopieren, um die Grundlagen unten zu erhalten - aber das schlägt fehl (UIImage +imageWithData: gibt nil zurück). Kann jemand sehen, warum das nicht funktionieren würde?Erstellen eines UIImage aus einem anderen UIImage mit imageWithData gibt null

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

Hinweis:

Ich habe auch versucht mit:

UInt8 * data = CFDataGetBytePtr (dataRef);

und einfach nur in NSData.

Gleiches Ergebnis.

+1

Warum DataWithBytesNoCopy? – jsicary

+0

dataWithBytesNoCopy wurde verwendet, da er den Puffer selbst mithilfe von malloc zugewiesen hat. Auf diese Weise erhält er während der gesamten Lebensdauer dieses Objekts Zugriff auf den eigentlichen Bildpuffer von image2. – Till

Antwort

1

Ich glaube, dass imageWithData dauert Bild-Datei-Daten, nicht Bild-Display-Daten, die Sie übergeben es ist. so etwas wie dies versucht:

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

UIImageJPegRepresentation() liefert die Daten, die Sie in eine Datei schreiben würden eine JPG-Datei auf der Festplatte zu erstellen. Das, bin ich 99.44% sicher, was imageWithData: will.

HINWEIS: wenn Sie schauen, um die Daten vor dem Erstellen image2 zu manipulieren, dann Sie tun die Anzeigedaten wollen, wobei in diesem Fall so, wie Sie ein Bild aus, dass wieder ein bisschen komplizierter ist, aber sieht etwas wie folgt aus:

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

(... der obige Code aus den Beispielen von Erica Sadun abgeleitet ist die smarte Teile sind sie, die Fehler sind all mine Aber das ist die allgemeine Idee, und es sollte funktionieren)