2013-08-28 3 views
2

NSMutableDictionary를 json'ed로 변환하려고합니다. 내 키 값 중 하나는 그림의 PNG 표현을위한 바이트입니다. NSJSONSerialization 무엇 UIImagePNGRepresenation 반환 NSData 객체 등의 작업을 수행하지 않기 때문에 그래서, 최대JSON 전송을 위해 UIImage를 인코딩하는 방법은 무엇입니까?

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

이 나중에 불면 뭔가를 가지고있다. 데이터를 인코딩하는 좋은 방법은 무엇입니까? 그냥 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; 

또한 아래의 Base64 솔루션보다 약 7 배 빠릅니다. 이 특별한 경우에는 그 속도가 AT ALL이 아니었지만 누군가가 물었습니다.

+0

base64와 같은 일종의 이진 -> ascii7 인코딩으로 인코딩해야하거나 양쪽 끝점을 제어 할 수있는 경우 JSON에 연결할 수있는 사진과 같은 항목에 대해 이진 스트림을 허용하는 끝점을 만듭니다 나중에 메타 데이터 봉투. 이 아키텍처는 일반적으로 장기적으로 훨씬 뛰어납니다. –

+1

Base64가 가장 확실한 해결책이 될 것입니다. 그러나 JSON에서 대량의 바이너리 데이터를 전송하는 것은 좋은 생각이 아닙니다. –

+1

+1 새 값 사전 리터럴을 사용하여 값을 설정합니다. – memmons

답변

3

JSON을 사용하여 전송할 수 있도록 이미지를 base64 문자열로 변환해야합니다. 다음은 link to download base64 class files입니다. NSData으로 이미지를 변환 그 후

[Base64 initialize]; 

를이 코드를 사용합니다 :

그런 다음 뷰 controller.m이 초기화 webdatNSData입니다

NSString *strEncoded = [Base64 encode:webDat]; 

합니다.

+0

매력처럼 작동했습니다! 감사! –

1

일반적으로 이미지는 JSON의 base64 문자열로 인코딩됩니다. NSData을 base64 문자열로 인코딩하는 기본 제공 방법은 없지만이를 수행하는 알고리즘은 상당히 잘 알려져 있습니다. 그래서 같은 NSData 카테고리 만들기 : JSON에 대한

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 

인코딩은 사소한된다 : iOS 장비로 촬영 한 이미지가 매우 큰

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

참고. 전송하는 바이트 수는 너비 x 높이 x 3과 같습니다. 예를 들어 iPhone 5에는 8MP 카메라 (3264 x 2448 x 3 = 23MB의 데이터)가 있습니다. JSON을 통해 많은 양의 데이터를 전송하고 싶지는 않습니다. 따라서 보내기 전에 사진을 잘라내거나 크기를 조정할 수 있습니다.

+0

jpeg, medium 품질로 변환합니다. 많이 작게 (~ 50kB) –

관련 문제