使用imageWithData从另一个UIImage创建UIImage返回nil。

5
我试图从一个UIImage中检索图像数据,对其进行修改,然后从中创建一个新的UIImage。 首先,我尝试仅复制数据而不进行任何修改以获得基础知识 - 但该方法失败了(UIImage + imageWithData:返回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]; 

注意:
我也尝试使用:
UInt8* data = CFDataGetBytePtr(dataRef);
并将其直接传输到NSData中。
结果相同。

1
why dataWithBytesNoCopy? - jsan
dataWithBytesNoCopy被使用是因为他使用malloc自己分配了缓冲区。这样,在整个对象的生命周期中,他将可以访问image2的实际图像缓冲区。 - Till
1个回答

1
我相信 imageWithData 函数需要的是“图像文件数据”,而不是你传递给它的“图像显示数据”。你可以尝试使用以下代码:
NSData * newData = UIImageJPEGRepresentation(image, 1.0);
UIImage *image2 = [UIImage imageWithData:newData]; 

UIImageJPegRepresentation() 返回的是你要写入文件以创建磁盘上的 .jpg 文件的数据。我有99.44%的把握这就是 imageWithData: 所需的。

注意:如果你想在创建 image2 之前操纵数据,那么你确实需要显示数据,此时从中获取图像的方式会更加复杂,但看起来类似于以下内容:

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

(上述代码源自Erica Sadun的示例。聪明的部分是她的,错误都是我的。但这是一个大致的想法,应该能够正常工作。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接