2

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

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

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

更新:

我最终找到了这个关于使用 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 倍。在这种特殊情况下,速度并不重要,但有人问。

4

2 回答 2

3

您需要将您的图像转换为 base64 字符串。这样您就可以使用 JSON 传递传输。这是下载 base64 类文件的链接

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

[Base64 initialize];

之后将您的图像转换为NSData并使用此代码:

NSString   *strEncoded = [Base64 encode:webDat];

哪里webdatNSData

于 2013-08-28T08:55:04.050 回答
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 有一个 8MP 摄像头,即 3264 x 2448 x 3 = 23MB 数据。您几乎不想通过 JSON 传输这么多数据。因此,您需要在发送前裁剪照片或将其调整为更易于管理的尺寸。

于 2013-08-28T03:11:24.037 回答