iPhone - 通过HTTP接收的图像损坏JPEG数据

时间:2009-06-30 17:22:42

标签: iphone cocoa-touch uiimage

我使用NSURLConnection通过HTTP获取图像,如下所示 -

NSMutableData *receivedData;

- (void)getImage {
    self.receivedData = [[NSMutableData alloc] init];
    NSURLConnection *theConnection = // create connection
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {    
   [receivedData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
   [connection release];

   UIImage *theImage = [UIImage imageWithData:receivedData];
}

通常它工作得很好,但有时我看到这会被记录 - :损坏的JPEG数据:数据段的过早结束

此时,图像无法完全渲染。我会看到它的75%,然后右下角是一个灰色的盒子。

有关如何解决此问题的任何想法?我不正确地构建我的图像吗?

5 个答案:

答案 0 :(得分:9)

您的HTTP代码看起来是正确的。您可能希望在完成加载后记录receivedData的大小,并将其与服务器上图像的预期大小进行比较。如果它是预期的大小,则可能是服务器上的图像本身已损坏。

答案 1 :(得分:3)

ASI-HTTP可以解决此问题。

NSURL *coverRequestUrl = [NSURL URLWithString:imageStringURL];
ASIHTTPRequest *coverRequest = [[ASIHTTPRequest alloc] initWithURL:coverRequestUrl];
[coverRequest setDelegate:self];
[coverRequest setDidFinishSelector:@selector(imageRecieved:)];

[appDelegate.queue addOperation:coverRequest];
[appDelegate.queue go];

appDelegate中的队列变量是ASINetwork队列对象。因为我发送异步请求,所以我使用它。

- (void)imageRecieved:(ASIHTTPRequest *)response
{
    UIImage *myImage = [UIImage imageWithData:[response responseData]];
}

答案 2 :(得分:2)

我通过使用NSMutableDictionary解决了这个问题。

NSMutableDictionary *dataDictionary;

在我的loadData函数中,我定义了我的数据:

NSMutableData *receivedData = receivedData = [[NSMutableData alloc] init];

然后我将数据加载到我的字典中,其中键是[theConnection description],对象是我的数据。

[dataDictionary setObject:receivedData forKey:[theConnection description]];

在代理中,我可以查找传递给委托的连接的正确数据对象并保存到正确的数据实例,否则我最终会遇到JPEG munging / corruption问题。

在didReceiveData中,我把:

//get the object for the connection that has been passed to connectionDidRecieveData and that object will be the data variable for that instance of the connection.
NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]];

//then act on that data
[theReceivedData appendData:data];

同样,在didReceiveResponse中,我把:

NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]];
[theReceivedData setLength:0];

在connectionDidFinishLoading中:     NSMutableData * theReceivedData = [dataDictionary objectForKey:[连接描述]];     img = [[UIImage alloc] initWithData:theReceivedData];

这看起来效果很好。顺便说一句,我的代码基于Apple's tutorial for NSUrlConnection,并添加了一个NSMutableDictionary来跟踪各个连接。我希望这有帮助。如果您希望我发布完整的图像处理代码,请与我们联系。

答案 3 :(得分:1)

我也见过这个。如果将数据保存到文件中然后将数据读回图像,则可以完美地工作。我怀疑jpeg图像数据中有http头信息。

希望有人找到解决方法,因为保存到文件的解决方法很糟糕。

// problem

UIImage *newImage = [UIImage imageWithData:receivedData];

// crappy workaround

[receivedData writeToFile:[NSString stringWithFormat:@"a.jpg"] atomically:NO];
UIImage *newImage = [UIImage imageWithContentsOfFile:@"a.jpg"];

答案 4 :(得分:0)

使用receivedData = [NSData dataWithBytes:receivedData.bytes length:receivedData.length]复制NSData内容也可能有所帮助(并且比保存和读取磁盘更有效。)

原因可能是原始的receivedData对象没有保留其内容(例如,使用[NSData dataWithBytesNoCopy:length:]创建时),并且在释放后尝试读取它们。

当您在创建NSData对象的线程中的另一个线程上遇到此问题时,可能会发生这种情况。