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

iPhone-通过HTTP接收的图像的损坏JPEG数据,iphone,cocoa-touch,uiimage,Iphone,Cocoa Touch,Uiimage,我使用NSURLConnection通过HTTP获得一个图像,如下所示- NSMutableData *receivedData; - (void)getImage { self.receivedData = [[NSMutableData alloc] init]; NSURLConnection *theConnection = // create connection } - (void)connection:(NSURLConnection *)connection

我使用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%,然后右下角是一个灰色框


关于如何解决这个问题有什么想法吗?我的映像构造不正确吗?

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

我也看到了这一点。如果您将数据保存到一个文件中,然后将数据读回一个图像中,它将非常有效。我怀疑jpeg图像数据中有http头信息

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

// problem

UIImage *newImage = [UIImage imageWithData:receivedData];

// crappy workaround

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

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中的我的队列变量是网络队列对象。因为我发送异步请求,所以我使用它

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

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

NSMutableDictionary *dataDictionary;
在我的loadData函数中,我定义了我的数据:

NSMutableData *receivedData = receivedData = [[NSMutableData alloc] init];
然后我将数据加载到字典中,其中键是[Connection description],对象是我的数据

[dataDictionary setObject:receivedData forKey:[theConnection description]];
这样,在委托中,我可以为传递给委托的连接查找正确的数据对象,并将其保存到正确的数据实例,否则最终会出现JPEG Mung/损坏问题

在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];
同样,在DidReceiverResponse中,我提出:

NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]];
[theReceivedData setLength:0];
在连接中,完成加载: NSMutableData*theReceivedData=[dataDictionary objectForKey:[连接描述]]; img=[[UIImage alloc]initWithData:theReceivedData]


这似乎很有效。顺便说一下,我的代码是基于添加了一个NSMutableDictionary来跟踪各个连接的。我希望这有帮助。如果您想让我发布完整的图像处理代码,请告诉我。

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

一个可能的原因是原始receivedData对象没有保留其内容(例如,使用
[NSData DATA WITHBYTESNOPY:length://code>创建时),并且您尝试在释放它们后读取它们


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

我已经下载了许多图像,但还没有看到这一点。你的图像非常大吗?这种情况会发生在其他设备(计算机、模拟器)上吗?它不是特别大,不会。我在iPhone和模拟器上都能看到它(但不是通过网络浏览器点击图像)。请检查您的互联网连接。谢谢,这帮了大忙。通过这样做,我意识到这是我自己的编程错误(我两次意外地触发了请求),我正在做与bpapa相同的事情。如果您向同一URL启动两个不同的NSURLConnections,最终结果可能是数据损坏。我遇到了完全相同的问题,原因确实是相同的:两个连接到同一个映像。创建此错误是因为两个连接共享同一数据源。在构建特定任务必须同时启动的应用程序时(您似乎无意中这样做了:),您要么必须为每个连接(一对一)创建一个唯一的数据源,要么创建一个信号量,这样您的可变数据源就不会同时被多个连接的结果序列化(竞争条件)。最终结果是创建损坏或不完整的数据!(这是你经历过的)。@bpapa-你在代码中的什么地方发出了两次请求?根据我的日志输出,我想我也这么做了,但我不明白为什么只有某些照片会被调用两次。我尝试过,但没有任何改变。我使用相同的方法。效果很好。在发送请求之前,确保在字典中alloc和init数据对象。否则你也会犯同样的错误