如何从NSData字符串数据创建CGImageRef(不是UIImage) [英] How to create CGImageRef from NSData string data (NOT UIImage)

查看:546
本文介绍了如何从NSData字符串数据创建CGImageRef(不是UIImage)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在没有UIImage的情况下创建新的CGImageRef?我不能使用image.CGImage

How does one create a new CGImageRef without a UIImage? I can't use image.CGImage

我正在从服务器进程接收作为std :: string的base64编码的图像.下面的代码的第一部分模拟了接收编码后的字符串.

I am receiving a base64 encoded image as a std::string from a server process. The first part of the code below simulates receiving the encoded 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将为nil.

When I get the encoded string, I need to get a CGImageRef to get the data back into the correct format to populate a UIImage. If the data is not in the correct format the UIImage will be nil.

我需要使用nsdataFromBase64String创建一个新的CGImageRef.

I need to create a new CGImageRef with the nsdataFromBase64String.

类似的东西:

    CGImageRef base64ImageRef = [newCGImageRefFromString:nsdataFromBase64String];

然后我可以使用imageWithCGImage将数据放入新的UIImage中.

Then I can use imageWithCGImage to put the data into a new UIImage.

类似的东西:

    UIImage *imageFromImageRef = [UIImage imageWithCGImage: base64ImageRef];

然后我可以返回UIImage.

Then I can return the UIImage.

    return newImage;
}

请注意,以下行将不起作用:

Please note that the following line will NOT work:

    UIImage *newImage = [[UIImage alloc] initWithData:nsdataFromBase64String];

数据必须采用正确的格式,否则UIImage将为nil.因此,我的问题是:如何使用NSData创建CGImageRef?"

The data needs to be in the correct format or the UIImage will be nil. Hence, my question, "How do I create a CGImageRef with NSData?"

推荐答案

简短的答案,因为这主要是针对我在NSChat中提到的内容:

Short-ish answer, since this is mostly just going over what I mentioned in NSChat:

  1. 弄清楚所接收图像的格式以及其大小(宽度和高度,以像素为单位).您在聊天中提到这只是ARGB8的直接数据,因此请记住这一点.我不确定您如何收到其他信息.

  1. Figure out what the format of the image you're receiving is as well as its size (width and height, in pixels). You mentioned in chat that it's just straight ARGB8 data, so keep that in mind. I'm not sure how you're receiving the other info, if at all.

使用CGImageCreate,使用已经知道的图像来创建新图像(即,大概知道其宽度,高度等等,如果不知道,则应将其与您要发送的图片).例如,没人喜欢写的这个样板包:

Using CGImageCreate, create a new image using what you know about the image already (i.e., presumably you know its width, height, and so on — if you don't, you should be packing this in with the image you're sending). E.g., this bundle of boilerplate that nobody likes to write:

// 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).

That code's written with the idea that it's guaranteed to be ARGB_8888, the data is correct, nothing could possibly return NULL, etc. Copy/pasting the above code could potentially cause everything in a three mile radius to explode. Error handling's up to you (e.g., CGColorSpaceCreateWithName can potentially return null).

使用CGImage分配UIImage.由于UIImage将拥有CGImage的所有权/复制该CGImage,因此释放您的CGImageRef(实际上,文档对 UIImage对CGImage所做的事情一无所知,但是您将不再使用它,因此您必须释放您的).

Allocate a UIImage using the CGImage. Since the UIImage will take ownership of/copy the CGImage, release your CGImageRef (actually, the docs say nothing about what UIImage does with the CGImage, but you're not going to use it anymore, so you must release yours).

这篇关于如何从NSData字符串数据创建CGImageRef(不是UIImage)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆