如何在没有UIImage的情况下创建新的CGImageRef?我无法使用image.CGImage
我从服务器进程收到base64编码的图像作为std :: string。下面代码的第一部分模拟接收编码的字符串。
- (UIImage *)testChangeImageToBase64String
{
UIImage *processedImage = [UIImage imageNamed:@"myFile.jpg"];
// UIImage to unsigned char *
CGImageRef imageRef = processedImage.CGImage;
NSData *data = (NSData *) CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef)));
// encode data to Base64 NSString
NSString *base64EncodedDataString = [data base64EncodedStringWithOptions:0];
// create encoded std::string
std::string encoded([base64EncodedDataString UTF8String]);
// ***************************************************************************
// This is where we call the server method and receive the bytes in a std::string
std::string received = encoded;
// ***************************************************************************
// get Base64 encoded std::string into NSString
NSString *base64EncodedCstring = [NSString stringWithCString:encoded.c_str() encoding:[NSString defaultCStringEncoding]];
// NSData from the Base64 encoded std::string
NSData *nsdataFromBase64String = [[NSData alloc]initWithBase64EncodedString:base64EncodedCstring options:0];
一切都很好!!!! .....直到我尝试填充newImage。
当我获得编码的字符串时,我需要获得CGImageRef
以将数据恢复为正确的格式以填充UIImage。 如果数据格式不正确,UIImage将为零。
我需要使用nsdataFromBase64String创建一个新的CGImageRef。
类似的东西:
CGImageRef base64ImageRef = [newCGImageRefFromString:nsdataFromBase64String];
然后我可以使用imageWithCGImage将数据放入一个新的UIImage。
类似的东西:
UIImage *imageFromImageRef = [UIImage imageWithCGImage: base64ImageRef];
然后我可以返回UIImage。
return newImage;
}
请注意,以下行不起作用:
UIImage *newImage = [[UIImage alloc] initWithData:nsdataFromBase64String];
数据需要格式正确,否则UIImage将为零。因此,我的问题,“如何使用NSData创建CGImageRef?”
答案 0 :(得分:3)
简短的回答,因为这主要是刚刚超过我在NSChat中提到的内容:
弄清楚您接收的图像格式及其大小(宽度和高度,以像素为单位)。你在聊天中提到它只是直接的ARGB8数据,所以请记住这一点。如果有的话,我不确定你是如何收到其他信息的。
使用CGImageCreate,使用你已经知道的图像创建一个新图像(也就是说,你可能知道它的宽度,高度等等 - 如果你不知道,你应该用它来包装它你正在发送的图像)。例如,这个没有人喜欢写的样板:
// NOTE: have not tested if this even compiles -- consider it pseudocode.
CGImageRef image;
CFDataRef bridgedData;
CGDataProviderRef dataProvider;
CGColorSpaceRef colorSpace;
CGBitmapInfo infoFlags = kCGImageAlphaFirst; // ARGB
// Get a color space
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
// Assuming the decoded data is only pixel data
bridgedData = (__bridge CFDataRef)decodedData;
dataProvider = CGDataProviderCreateWithCFData(bridgedData);
// Given size_t width, height which you should already have somehow
image = CGImageCreate(
width, height, /* bpc */ 8, /* bpp */ 32, /* pitch */ width * 4,
colorSpace, infoFlags,
dataProvider, /* decode array */ NULL, /* interpolate? */ TRUE,
kCGRenderingIntentDefault /* adjust intent according to use */
);
// Release things the image took ownership of.
CGDataProviderRelease(dataProvider);
CGColorSpaceRelease(colorSpace);
该代码的写法是保证它是ARGB_8888,数据是正确的,没有任何东西可能返回NULL等。复制/粘贴上面的代码可能会导致半径3英里内的所有内容爆炸。错误处理取决于您(例如,CGColorSpaceCreateWithName可能会返回null)。
使用CGImage分配UIImage。由于UIImage将拥有/复制CGImage,释放你的CGImageRef(实际上,文档没有说明 UIImage用CGImage做什么,但是你不再使用它了,所以你必须释放你的。)