2010-03-02 83 views
4

我正在使用我的iPhone应用程序中的Web服务。 Web服务方法返回一个包含多个字段(例如ID,说明等)的响应。其中一个字段包含我需要在iPhone应用程序中转换为UIImage的二进制图像数据。从Web服务读取二进制图像数据到UIImage

我正在成功使用NSXMLParser从XML响应提取数据。在XMLParser的parser:foundCharacters:选择器中,它给出NSString*指向每个字段内的字符串。由于这是一个字符串,这是我做的,当我遇到像场读取图像数据的内容:

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

但IMG变量仍然是“零”这一行之后。看起来像来自XML字符串的数据与转换不兼容。我在这里做错了什么? (我能够读取等领域为我的变量,但不是这个图像数据字段)提前

谢谢..

回答

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[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 

@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 

谢谢大家!

+0

我有像你一样的确切问题。我很高兴我找到了你的答案,但我并不真正了解代码,我应该如何使用它。我有一个字符串currentElementValue,我从一个Web服务解析,我想将其转换成nsdata,以便我可以进一步转换成图像。你能给我几点建议吗?谢谢。 – alin 2012-11-16 12:49:23

+1

也许这个答案很晚。但您可以使用示例中提供的方法,并像这样调用它: NSData * data = [NSData dataWithBase64EncodedString:currentElementValue]; UIImage * img = [UIImage imageWithData:data]; – ravinsp 2013-03-06 07:33:53

1

诀窍与NSString的是,有一个与它所包含的数据相关联的隐含编码。但是,您接收的图像可能采用无法正确转换的格式,因为它可能是二进制数据,也可能是二进制数据的无损编码(如base64)。诀窍是确保您不要让NSString执行任何编码转换,否则您的图像数据将被损坏。我会尝试使用更像getBytes:maxLength:usedLength:encoding:options:range:remainingRange的API,而不是使用dataUsingEncoding:。虽然比dataUsingEncoding:更复杂,但我认为它会为您提供灵活性,您只需从NSString获取的数据即可,仅此而已。

+0

感谢您的宝贵意见,但是再次,我需要知道字符串中的字节数。我怎么知道? '[string length]'和'[string lengthOfBytesUsingEncoding]'都涉及字符编码。如果我可以知道字节长度,我可以使用[string getCString]来获取原始字节。再次感谢。 – ravinsp 2010-03-02 05:35:46