如何编码UIImage进行JSON传输?

时间:2013-08-28 00:24:19

标签: ios objective-c json cocoa-touch ios6

我正在尝试建立一个NSMutableDictionary来转换为json'ed。我的一个键值是图片的png表示的字节。所以我有类似

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

后来会爆炸,因为NSJSONSerialization不会执行NSData对象之类的事情,这是UIImagePNGRepresenation返回的内容。什么是编码数据的好方法?只是UTF8'可能会很糟糕。我不熟悉json中合法字符串表示的内容。

更新

我最终找到this link关于使用Apple内置但未公开的功能。代码更长,但我减少了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倍。在这种特殊情况下,速度并不重要,但有人问道。

2 个答案:

答案 0 :(得分:3)

您需要将图像转换为base64字符串。因此您可以使用JSON传递传输。这是link to download base64 class files

然后在视图controller.m中初始化它:

[Base64 initialize];

之后将图片转换为NSData并使用此代码:

NSString   *strEncoded = [Base64 encode:webDat];

其中webdatNSData

答案 1 :(得分: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传输那么多数据。因此,在发送之前,您需要裁剪照片或将其调整为更易于管理的内容。