¿La mayoría de la manera eficiente de save una foto en el disco en el iPhone?

Desde el perfil con los Instruments , he aprendido que la forma en que estoy guardando imágenes en el disco está dando como resultado picos de memory de ~60MB . Esto hace que la aplicación emita low memory warnings , lo que (de manera inconsistente) lleva a fallas en el iPhone4S con iOS7 .

Necesito la forma más eficiente de save una image en el disco.

Actualmente estoy usando este código

 + (void)saveImage:(UIImage *)image withName:(NSString *)name { NSData *data = UIImageJPEGRepresentation(image, 1.0); DLog(@"*** SIZE *** : Saving file of size %lu", (unsigned long)[data length]); NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:name]; [fileManager createFileAtPath:fullPath contents:data attributes:nil]; } 

Notas:

  1. Reducir el valor del argumento compressionQuality en UIImageJPEGRepresentation no networkinguce el pico de memory de manera significativa. p. ej., calidad de compressionQuality = 0.8 , networkingujo el pico de memory en 3 3MB en promedio en más de 100 grabaciones. Sin embargo, networkinguce el tamaño de los datos en el disco (obviamente), pero esto no me ayuda.

  2. UIImagePNGRepresentation en lugar de UIImageJPEGRepresentation es peor para esto. Es más lento y da como resultado picos más altos.

¿Es posible que este enfoque con ImageIO sea ​​más eficiente? Si es así, ¿por qué?

Si alguien tiene alguna sugerencia sería genial. Gracias

Editar:

Notas sobre algunos de los puntos descritos en las preguntas a continuación.

a) Aunque estaba guardando varias imágenes, no las estaba guardando en un ciclo. Hice un poco de lectura y testings y descubrí que un grupo de autorelease no me ayudaría.

b) Las fotos no tenían un tamaño de 60 Mb cada una. Eran fotos tomadas en el iPhone 4S.

Con esto en mente volví a tratar de superar lo que pensaba que era el problema; la línea NSData *data = UIImageJPEGRepresentation(image, 1.0); .

Los picos de memory que causaron el locking se pueden ver en la siguiente captura de pantalla. Correspondían a cuando se llamaba UIImageJPEGRepresentation . También ejecuté Time Profiler y el System Usage que me indicó en la misma dirección.

introduzca la descripción de la imagen aquí

Larga historia, me mudé a AVFoundation y tomé los datos de la image fotográfica usando

photoData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];

Que devuelve un object de tipo NSData , luego lo utilicé como datos para escribir usando NSFileManager.

Esto elimina completamente los picos en la memory.

es decir

 [self saveImageWithData:photoData]; 

dónde

 + (void)saveImageWithData:(NSData *)imageData withName:(NSString *)name { NSData *data = imageData; DLog(@"*** SIZE *** : Saving file of size %lu", (unsigned long)[data length]); NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:name]; [fileManager createFileAtPath:fullPath contents:data attributes:nil]; } 

PS: No he puesto esto como una respuesta a la pregunta en la que las personas sienten que no responde al Título "¿La mayoría de la forma más eficiente para save una foto en el disco en el iPhone?". Sin embargo, si el consenso es que debería ser, puedo actualizarlo.

Gracias.

El uso de UIImageJPEGRrepresentación requiere que tenga la image original y final en la memory al mismo time. También puede almacenar en caching la image completamente renderizada por un time, lo que usaría mucha memory.

Podrías intentar usar una CGImageDestination . No sé cómo es la memory eficiente, pero tiene el potencial de transmitir la image directamente al disco.

 +(void) writeImage:(UIImage *)inImage toURL:(NSURL *)inURL withQuality:(double)inQuality { CGImageDestinationRef destination = CGImageDestinationCreateWithURL( (CFURLRef)inURL , kUTTypeJPEG , 1 , NULL ); CFDictionaryRef properties = (CFDictionaryRef)[NSDictionary dictionaryWithObject:[NSNumber numberWithDouble:inQuality] forKey:kCGImageDestinationLossyCompressionQuality]; CGImageDestinationAddImage( destination , [inImage CGImage] , properties ); CGImageDestinationFinalize( destination ); CFRelease( destination ); } 

¿Están realmente comprimidas sus imágenes 60 MB cada una? Si lo son, no es mucho lo que puede hacer si desea savelos como un solo file JPEG. Puede intentar convertirlos en imágenes más pequeñas, o mosaicos y savelos en files separados.

No espero que su fragment de código ImageIO mejore nada. Si hubiera una solución de dos líneas, entonces UIImageJPEGRepresentation lo estaría usando internamente.

Pero apuesto a que no obtienes 60 MB de una sola image. Estoy apostando que obtienes 60 MB de varias imágenes guardadas en un bucle. Y si ese es el caso, entonces es probable que puedas hacer algo. Pon una @autoreleasepool{} dentro de tu ciclo. Es muy posible que estés acumulando objects autoelegidos, y eso lleva a la espiga. Agregar un grupo dentro de su ciclo le permite drenar.

Intente utilizar NSAutoReleasePool y drene el grupo una vez que termine de escribir los datos.