4

iPhoneアプリでWebサービスを利用しています。Webサービスメソッドは、いくつかのフィールド(ID、説明など)を持つ応答を返します。これらのフィールドの1つには、iPhoneアプリケーションでUIImageに変換する必要があるバイナリイメージデータが含まれています。

NSXMLParserを使用して、XML応答からデータを正常に抽出しています。parser:foundCharacters:XMLParserのセレクターでは、NSString*各フィールド内の文字列を指し示します。これは文字列であるため、画像フィールドに遭遇したときに画像データを読み取るためにこれを行います。

UIImage *img = [[UIImage alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]];

ただし、この行の後、img変数はまだ「nil」です。XML文字列からのデータは変換と互換性がないようです。私はここで何が間違っているのですか?(他のフィールドを変数に読み込むことはできますが、この画像データフィールドを読み込むことはできません)

前もって感謝します..

4

2 に答える 2

5

fbrereto の回答に従って、次のリンクのコード サンプルを使用して文字列を NSData に変換することができました: http://www.cocoadev.com/index.pl?BaseSixtyFour (MiloBird ユーザーによるコード サンプルにスクロールします)。これで、イメージを正常に構築できます。

これは、objective-c カテゴリを使用してセレクター+ (id)dataWithBase64EncodedString:(NSString *)string;を NSData クラスに追加します。上記のリンクから抽出した必要なコード サンプルを次に示します。

//MBBase64.h

@interface NSData (MBBase64)

+ (id)dataWithBase64EncodedString:(NSString *)string;     //  Padding '=' characters are optional. Whitespace is ignored.

@end


//MBBase64.m

static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

@implementation NSData (MBBase64)

+ (id)dataWithBase64EncodedString:(NSString *)string;
{
    if (string == nil)
        [NSException raise:NSInvalidArgumentException format:nil];
    if ([string length] == 0)
        return [NSData data];

    static char *decodingTable = NULL;
    if (decodingTable == NULL)
    {
        decodingTable = malloc(256);
        if (decodingTable == NULL)
            return nil;
        memset(decodingTable, CHAR_MAX, 256);
        NSUInteger i;
        for (i = 0; i < 64; i++)
            decodingTable[(short)encodingTable[i]] = i;
    }

    const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
    if (characters == NULL)     //  Not an ASCII string!
        return nil;
    char *bytes = malloc((([string length] + 3) / 4) * 3);
    if (bytes == NULL)
        return nil;
    NSUInteger length = 0;

    NSUInteger i = 0;
    while (YES)
    {
        char buffer[4];
        short bufferLength;
        for (bufferLength = 0; bufferLength < 4; i++)
        {
            if (characters[i] == '\0')
                break;
            if (isspace(characters[i]) || characters[i] == '=')
                continue;
            buffer[bufferLength] = decodingTable[(short)characters[i]];
            if (buffer[bufferLength++] == CHAR_MAX)      //  Illegal character!
            {
                free(bytes);
                return nil;
            }
        }

        if (bufferLength == 0)
            break;
        if (bufferLength == 1)      //  At least two characters are needed to produce one byte!
        {
            free(bytes);
            return nil;
        }

        //  Decode the characters in the buffer to bytes.
        bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
        if (bufferLength > 2)
            bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
        if (bufferLength > 3)
            bytes[length++] = (buffer[2] << 6) | buffer[3];
    }

    realloc(bytes, length);
    return [NSData dataWithBytesNoCopy:bytes length:length];
}

@end

皆さん、ありがとうございました!

于 2010-03-04T05:18:21.123 に答える
1

の秘訣NSStringは、そこに含まれるデータに関連付けられた暗黙のエンコーディングがあることです。ただし、受信する画像は、バイナリデータまたはバイナリデータのロスレスエンコーディング(base64など)であるため、適切に変換されない形式である可能性があります。NSStringしたがって、秘訣は、エンコーディング変換をまったく実行させないようにすることです。そうしないと、画像データが破損します。を使用する代わりに、のdataUsingEncoding:ようなAPIを試してみますgetBytes:maxLength:usedLength:encoding:options:range:remainingRange。私が思うよりも複雑ですが、NSStringからデータだけdataUsingEncoding:を取得するために必要な柔軟性が得られます。

于 2010-03-02T05:01:17.133 に答える