我正在尝试从一个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];
Run Code Online (Sandbox Code Playgroud)
注意:
我也试过用:
UInt8*data = CFDataGetBytePtr(dataRef);
并直接管道进入NSData.
结果相同.
我相信 imageWithData 采用image-file-data,而不是 image-display-data ,这就是您传递的内容。尝试这样的事情:
NSData * newData = UIImageJPEGRepresentation(image, 1.0);
UIImage *image2 = [UIImage imageWithData:newData];
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
(上面的代码源自 Erica Sadun 的示例。聪明的部分是她的;错误都是我的。但这是总体思路,应该可行。)