【问题标题】:How to create CGImageRef from NSData string data (NOT UIImage)如何从 NSData 字符串数据(不是 UIImage)创建 CGImageRef
【发布时间】:2014-09-13 21:47:25
【问题描述】:

如何在没有 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 将为 nil。

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

类似:

    CGImageRef base64ImageRef = [newCGImageRefFromString:nsdataFromBase64String];

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

类似:

    UIImage *imageFromImageRef = [UIImage imageWithCGImage: base64ImageRef];

然后我可以返回 UIImage。

    return newImage;
}

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

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

数据需要采用正确的格式,否则 UIImage 将为 nil。因此,我的问题是“如何使用 NSData 创建 CGImageRef?”

【问题讨论】:

    标签: objective-c uiimage cgimage


    【解决方案1】:

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

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

    2. 使用 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 等。复制/粘贴上述代码可能会导致三英里半径内的所有内容爆炸。错误处理取决于您(例如,CGColorSpaceCreateWithName 可能返回 null)。

    3. 使用 CGImage 分配 UIImage。由于 UIImage 将获得/复制 CGImage 的所有权,因此请释放您的 CGImageRef(实际上,文档没有说明 UIImage 对 CGImage 做了什么,但您不会再使用它了,所以您必须释放你的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多