2013-08-28 37 views
2

我想建立一個NSMutableDictionary被轉換爲json'ed。我的一個鍵值是圖片的png表示的字節數。所以,我有類似如何爲JSON傳輸編碼UIImage?

NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc] init]; 
.... 
if ([self hasPhoto]) 
{ 
    result[@"photo"] = UIImagePNGRepresentation(self.photo); 
} 

這以後的打擊了,因爲NSJSONSerialization不會做這樣的事情NSData對象是什麼UIImagePNGRepresenation回報。什麼是編碼數據的好方法?只是UTF8'ing可能會很糟糕。我並不熟悉json中合法字符串表示的內容。

更新:

我最終找到this link關於使用蘋果的內置但是未公開功能。代碼較長,但我是2個文件少:

NSData *data = UIImageJPEGRepresentation(self.photo, 0.5); 
NSString *base64 = nil; 
NSUInteger sourceLength = data.length; 
NSUInteger encodeBufferLength = ((sourceLength + 2)/3) * 4 + 1; 
char *encodeBuffer = malloc(encodeBufferLength); 
int encodedRealLength = b64_ntop(data.bytes, sourceLength, encodeBuffer, encodeBufferLength); 
if (encodedRealLength >= 0) 
{ 
    base64 = [[NSString alloc] initWithBytesNoCopy: encodeBuffer length: encodedRealLength + 1 encoding: NSASCIIStringEncoding freeWhenDone: YES]; 
} 
else 
{ 
    free(encodeBuffer); 
} 
result[@"photo-jpeg"] = base64; 

這也運行約7X除了下面的Base64編碼解決方案快。在這個特殊情況下,並非所有速度都重要,但有人問。

+0

您需要將其編碼爲像base64這樣的binary-> ascii7編碼,或者如果您對兩個端點都有一定的控制權,則可以爲端點接受二進制流,以處理諸如可以將它們關聯到JSON的照片元數據信封。從長遠來看,這種架構通常要好得多。 –

+1

Base64將是最明顯的解決方案。但是用JSON傳輸大量的二進制數據可能不是一個好主意。 –

+1

+1使用新的字典文字設置您的價值。 – memmons

回答

3

您需要將圖像轉換爲base64字符串。因此您可以使用JSON傳遞傳輸。這裏是link to download base64 class files

然後在您的視圖Controller.m或者初始化這個:

[Base64 initialize]; 

之後,你的圖像轉換成NSData和使用此代碼:

NSString *strEncoded = [Base64 encode:webDat]; 

其中webdatNSData

+0

像魅力一樣工作!謝謝! –

1

通常,圖像被編碼爲JSON的base64字符串。沒有內置的方法來將NSData編碼爲base64字符串,但是這樣做的算法是衆所周知的。創建NSData類,像這樣:

static char encodingTable[64] = { 
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 
    'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 
    'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 
    'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' }; 

@implementation NSData (Base64) 

- (NSString *) base64EncodingWithLineLength:(unsigned int) lineLength { 
    const unsigned char *bytes = [self bytes]; 
    NSMutableString *result = [NSMutableString stringWithCapacity:[self length]]; 
    unsigned long ixtext = 0; 
    unsigned long lentext = [self length]; 
    long ctremaining = 0; 
    unsigned char inbuf[3], outbuf[4]; 
    short i = 0; 
    short charsonline = 0, ctcopy = 0; 
    unsigned long ix = 0; 

    while(YES) { 
     ctremaining = lentext - ixtext; 
     if(ctremaining <= 0) break; 

     for(i = 0; i < 3; i++) { 
      ix = ixtext + i; 
      if(ix < lentext) inbuf[i] = bytes[ix]; 
      else inbuf [i] = 0; 
     } 

     outbuf [0] = (inbuf [0] & 0xFC) >> 2; 
     outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); 
     outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); 
     outbuf [3] = inbuf [2] & 0x3F; 
     ctcopy = 4; 

     switch(ctremaining) { 
      case 1: 
       ctcopy = 2; 
       break; 
      case 2: 
       ctcopy = 3; 
       break; 
     } 

     for(i = 0; i < ctcopy; i++) 
      [result appendFormat:@"%c", encodingTable[outbuf[i]]]; 

     for(i = ctcopy; i < 4; i++) 
      [result appendFormat:@"%c",'=']; 

     ixtext += 3; 
     charsonline += 4; 

     if(lineLength > 0) { 
      if (charsonline >= lineLength) { 
       charsonline = 0; 
       [result appendString:@"\n"]; 
      } 
     } 
    } 

    return result; 
} 

@end 

編碼JSON則變得微不足道:

NSData *imageData = UIImagePNGRepresentation(self.photo); 
NSString *base64String = [imageData base64EncodingWithLineLength:0]; 
result[@"photo] = base64String; 

注意,與iOS設備拍攝的圖像是相當大的。您傳輸的字節數等於寬x高x 3。例如,iPhone 5具有800萬像素攝像頭,即3264 x 2448 x 3 = 23MB數據。你幾乎從不想通過JSON傳輸那麼多的數據。所以,在發送之前,您需要裁剪照片或將其調整到更易於管理的位置。

+0

我把它變成一個jpeg,中等質量。小得多(〜50kB) –