12

Ich erzeuge eine Reihe von Fliesen für CATiledLayer. Es dauert ungefähr 11 Sekunden, um 120 Kacheln bei 256 x 256 mit 4 Detailstufen auf einem iPhone 4S zu erzeugen. Das Bild selbst passt in 2048 x 2048.Irgendeine Möglichkeit, ein PNG schneller als UIImagePNGRepresentation zu kodieren?

Mein Engpass ist UIImagePNGRepresentation. Es dauert ungefähr 0,10 bis 0,15 Sekunden, um jedes 256 x 256 Bild zu erzeugen.

Ich habe versucht, mehrere Kacheln auf verschiedenen Hintergrundwarteschlangen zu generieren, aber das reduziert es nur auf ca. 9-10 Sekunden.

Ich habe auch versucht, den Rahmen wie dies mit Code ImageIO mit:

- (void)writeCGImage:(CGImageRef)image toURL:(NSURL*)url andOptions:(CFDictionaryRef) options 
{ 
    CGImageDestinationRef myImageDest = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, (__bridge CFStringRef)@"public.png", 1, nil); 
    CGImageDestinationAddImage(myImageDest, image, options); 
    CGImageDestinationFinalize(myImageDest); 
    CFRelease(myImageDest); 
} 

Während diese kleineren Dateien PNG erzeugt (win!), Dauert es etwa 13 Sekunden, 2 Sekunden mehr als zuvor.

Gibt es eine Möglichkeit, ein PNG-Bild von CGImage schneller zu kodieren? Vielleicht funktioniert eine Bibliothek, die NEON ARM-Erweiterung (iPhone 3GS +) wie libjpeg-turbo nutzt?

Gibt es vielleicht ein besseres Format als PNG zum Speichern von Kacheln, das nicht viel Platz einnimmt?

Die einzige praktikable Option, die ich mir vorstellen konnte, ist, die Kachelgröße auf 512 x 512 zu erhöhen. Dies verkürzt die Kodierungszeit um die Hälfte. Ich bin mir nicht sicher, was das mit meiner Scroll-Ansicht machen wird. Die App ist für iPad 2+ und unterstützt nur iOS 6 (mit iPhone 4S als Baseline).

Antwort

4

Es stellt sich heraus, warum UIImageRepresentation so schlecht ausführte war, weil es das Originalbild jedes Mal obwohl ich dachte Dekomprimieren wurde ich mit CGImageCreateWithImageInRect ein neues Bild zu schaffen.

Sie können die Ergebnisse von Instrumenten siehe hier:

enter image description here

Hinweis _cg_jpeg_read_scanlines und decompress_onepass.

I war kraft Dekomprimieren des Bildes mit diesem:

UIImage *image = [UIImage imageWithContentsOfFile:path]; 
UIGraphicsBeginImageContext(CGSizeMake(1, 1)); 
[image drawAtPoint:CGPointZero]; 
UIGraphicsEndImageContext(); 

Der Zeitpunkt dieser etwa 0,10 Sekunden betrug, fast äquivalent zu der von jedem UIImageRepresentation Anruf benötigte Zeit.

Es gibt zahlreiche Artikel über das Internet, die das Zeichnen als eine Art der Entkomprimierung eines Bildes empfehlen.

Es gibt einen Artikel über Kakaotics Avoiding Image Decompression Sickness. Der Artikel bietet eine alternative Möglichkeit zum Laden des Bildes:

NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] 
               forKey:(id)kCGImageSourceShouldCache]; 
CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)[[NSURL alloc] initFileURLWithPath:path], NULL); 
CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)dict); 
UIImage *image = [UIImage imageWithCGImage:cgImage]; 
CGImageRelease(cgImage); 
CFRelease(source); 

Und jetzt dauert der gleiche Prozess ca. 3 Sekunden! Wenn Sie GCD verwenden, um Kacheln parallel zu generieren, verringert sich die Zeit signifikant.

Die obige Funktion writeCGImage dauert etwa 5 Sekunden. Da die Dateigrößen kleiner sind, vermute ich, dass die zlib-Komprimierung auf einem höheren Level ist.

Verwandte Themen