2014-07-22 31 views
3

如何在不使用UIImage的情況下創建新的CGImageRef?我不能使用image.CGImage如何從NSData字符串數據(不是UIImage)創建CGImageRef

我正在從服務器進程接收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的是nil。因此,我的問題是:「如何使用NSData創建CGImageRef?」

回答

2

短上下的答案,因爲這是大多隻是在看我在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的影響,但是您不再使用它,因此您必須釋放它)。