2012-02-13 17 views
7

Używam ALAsset do pobierania obrazów tak:Jak szybko zapisać plik ALAsset na dysku na iOS?

[[asset defaultRepresentation] fullResolutionImage]] 

Ten powrót CGImageRef który chcę zapisać na dysk tak szybko, jak to możliwe ...

Rozwiązanie 1:

UIImage *currentImage = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]]; 
NSData *currentImageData = UIImagePNGRepresentation(currentImage); 
[currentImageData writeToFile:filePath atomically:YES]; 

Rozwiązanie 2:

CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:filePath]; 
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL); 
CGImageDestinationAddImage(destination, [[asset defaultRepresentation] fullResolutionImage], nil); 
CGImageDestinationFinalize(destination); 

Problem polega na tym, że obie metody są bardzo powolne wykonywanie na urządzeniu. Wykonanie tego zajmuje około 2 sekund na obraz. I to absolutnie za długo.

Pytanie: Jak mogę przyspieszyć proces zapisywania obrazu? A może jest lepsze rozwiązanie tego?

AKTUALIZACJA: Najlepsze ulepszenia wydajności w obu rozwiązaniach to zapisywanie obrazów w formacie JPEG zamiast w formacie PNG. Tak więc dla rozwiązania 1 zastąpiono UIImagePNGRepresentation z UIImageJPEGRepresentation. Dla rozwiązania 2 wymieniono kUTTypePNG na kUTTypeJPEG.

Warto również zauważyć, że drugie rozwiązanie jest o wiele wydajniejsze pod względem pamięci niż pierwsze.

Odpowiedz

2

To dlatego, że kompresja PNG jest procesem powolnym i zajmuje trochę czasu na procesorze iPhone'a, szczególnie w przypadku pełnowymiarowej fotografii.

+0

Rozumiem. Ale czy istnieje inny, bardziej skuteczny sposób na zrobienie tego? Nie potrzebuję PNG. Właściwie każdy format jest w porządku. Po prostu muszę skopiować oryginalny obraz z ALAsset do mojego folderu niestandardowego ...? Dziękujemy –

+0

Czy wypróbowałeś UIImageJPEGRepresentation? –

+0

Po prostu próbowałem z reprezentacją JPEG - jest o połowę szybszy niż reprezentacja PNG (nadal około 1 sekundy). To jest dużo lepsze. Ale wciąż nie to, czego się spodziewałem. Czy jest coś jeszcze? A co z różnicą między obydwoma rozwiązaniami, o których pisałem. Ma jakąkolwiek przewagę nad drugą? –

1

Nie ma w taki sposób, aby przyspieszyć ten proces, ale możliwym rozwiązaniem byłoby wykorzystanie wątków, w ten sposób, że nie będzie blokował mainthread i będzie oferować użytkownikowi większy komfort:

dispatch_queue_t dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_async(dispatchQueue, ^(void) { 
    // Your code here 
}); 
+0

To jest to, co już zrobiłem ... –

9

Zamiast tego można skopiować tylko nieprzetworzone dane.
Ma to zalety polegające na tym, że nie można ponownie kodować pliku, nie zwiększając jego rozmiaru, nie tracąc jakości dzięki dodatkowej kompresji i zachowaniu jakichkolwiek danych meta w pliku. Powinien być również najszybszy sposób.
Zakładając, że masz theAsset i filepath, aby go zapisać.
Powinny również dodać obsługę błędów.

long long sizeOfRawDataInBytes = [[theAsset defaultRepresentation] size]; 
NSMutableData* rawData = [NSMutableData dataWithLength:(NSUInteger) sizeOfRawDataInBytes]; 
void* bufferPointer = [rawData mutableBytes]; 
NSError* error=nil; 
[[theAsset defaultRepresentation] getBytes:bufferPointer 
           fromOffset:0 
            length:sizeOfRawDataInBytes 
            error:&error]; 
if (error) 
{ 
    NSLog(@"Getting bytes failed with error: %@",error); 
} 
else 
{ 
    [rawData writeToFile:filepath 
       atomically:YES]; 
} 
+0

Problem polega na tym, że orientacja obrazu jest utracona – rydgaze

+0

Czy jesteś pewien, że nie ma w meta danych exif? – GusOst

+0

Informacja ta znajduje się w meta danych exif. – GusOst

Powiązane problemy