2009-06-30 10 views
7

Dostaję obraz przez HTTP za pomocą NSURLConnection, jak następuje -iPhone - Dane Corrupt JPEG dla obrazu otrzymanych przez 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]; 
} 

Zazwyczaj to działa dobrze, ale czasami widzę to się zalogować -: Uszkodzone dane JPEG: przedwczesny koniec segmentu danych

W tym momencie obraz nie jest całkowicie renderowany. Zobaczę może 75% tego, a następnie dolny prawy róg to szare pole.

Wszelkie pomysły, jak podejść do tego problemu? Czy niewłaściwie buduję moje zdjęcie?

+0

Pobierałem wiele zdjęć i jeszcze tego nie widziałem. Czy obraz jest wyjątkowo duży? Czy dzieje się to na innych urządzeniach (komputerze, symulatorze)? –

+0

Nie jest szczególnie duży, nie. I widzę to zarówno na iPhonie, jak i na symulatorze (ale nie na obrazie za pośrednictwem przeglądarki internetowej). – bpapa

+0

Sprawdź również swoje połączenia internetowe. –

Odpowiedz

9

Twój kod HTTP wygląda poprawnie. Możesz zapisać rozmiar odebranych danych po ich załadowaniu i porównać je z oczekiwanym rozmiarem obrazu na serwerze. Jeśli jest to oczekiwany rozmiar, być może sam obraz jest uszkodzony na serwerze.

+7

Dzięki, to bardzo pomogło. Robiąc to zdałem sobie sprawę, że to był mój własny błąd programowania (przypadkowo odpaliłem żądanie dwukrotnie). – bpapa

+1

Robiłem to samo, co bpapa. Wygląda na to, że jeśli uruchomisz 2 różne połączenia NSURLConnection z tym samym adresem URL, wynikiem końcowym będą uszkodzone dane. – CornPuff

+1

Mam dokładnie ten sam problem, i to było rzeczywiście z tej samej przyczyny: 2 połączenia z tym samym obrazem. –

1

Widziałem to również. Jeśli zapiszesz dane w pliku, a następnie odczytasz dane z powrotem do obrazu, działa to doskonale. Podejrzewam, że w danych obrazu jpeg znajdują się informacje nagłówka http.

Mam nadzieję, że ktoś znajdzie rozwiązanie tego problemu, ponieważ obejście problemu z zapisaniem na plik jest do dupy.

// problem 

UIImage *newImage = [UIImage imageWithData:receivedData]; 

// crappy workaround 

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

Wypróbowałem i nic nie zmienia – Abramodj

3

ASI-HTTP może rozwiązać ten problem.

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]; 

Moja zmienna kolejki w appDelegate to obiekt kolejki ASINetwork. Ponieważ wysyłam asynchroniczne żądanie, więc używam go.

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

Rozwiązałem ten problem, używając NSMutableDictionary.

NSMutableDictionary *dataDictionary; 

W mojej funkcji loaddata, definiować moje dane:

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

Potem załadować dane do mojego słownika gdzie jest klucz [opis theConnection], a obiekt jest moje dane.

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

ten sposób w delegatów, mogę zajrzeć do prawidłowego obiektu danych dla połączenia, która jest przekazywana do delegata i zapisać na przykład właściwe dane inaczej skończyć z problemem munging/korupcyjnej JPEG.

W didReceiveData, umieścić:

//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]; 

Podobnie w didReceiveResponse, umieścić:

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

A connectionDidFinishLoading: NSMutableData * theReceivedData = [dataDictionary objectForKey [opis połączenia]] ; img = [[UIImage alloc] initWithData: theReceivedData];

I to wydaje się działać bardzo dobrze. Przy okazji, mój kod jest oparty na Apple's tutorial for NSUrlConnection z dodatkiem NSMutableDictionary, aby śledzić poszczególne połączenia. Mam nadzieję, że to pomoże. Daj mi znać, jeśli chcesz, żebym opublikował mój pełny kod obsługi obrazu.

+0

Używam tej samej metody. Działa świetnie. Upewnij się, że przydzieliłeś i zainicjowałeś obiekt danych w słowniku przed wysłaniem żądania. W przeciwnym razie skończy się ten sam błąd – JWKothe

0

Kopiowanie zawartości NSData przy użyciu receivedData = [NSData dataWithBytes:receivedData.bytes length:receivedData.length] również może być pomocne (i jest bardziej efektywne niż zapisywanie i odczytywanie z dysku).

Możliwą przyczyną jest to, że oryginalny obiekt receiveData nie zachowuje swojej zawartości (np. Gdy został utworzony przy użyciu [NSData dataWithBytesNoCopy:length:]) i próbujesz je odczytać po ich zwolnieniu.

Jest to prawdopodobne, gdy wystąpi ten problem w innym wątku z wątku, który utworzył obiekt NSData.

Powiązane problemy