2009-03-12 9 views
7

Cuando se agrega un PNG a un proyecto de XCode iPhone, el compilador lo optimiza mediante pngcrush. Una vez en el dispositivo, el rendimiento de representación de la imagen es muy rápido.Realización de la optimización de iPhone en PNG descargados externamente

Mi problema es que mi aplicación descarga sus PNG desde una fuente externa en tiempo de ejecución (desde los álbumes web de Picasa, usando las API de datos de Google). Desafortunadamente, el rendimiento de estas imágenes es bastante malo. Cuando hago un renderizado personalizado en la parte superior de la imagen, parece 100 veces más lento que sus equivalentes almacenados internamente. Sospecho fuertemente que esto es porque las imágenes descargadas no han sido optimizadas.

¿Alguien sabe cómo puedo optimizar un archivo PNG descargado externamente en tiempo de ejecución en el iPhone? Estoy esperando una clase que haga esto. Incluso consideré agregar el código fuente de pngcrush a mi aplicación, lo que parece drástico. No he podido encontrar una respuesta decente yo mismo. Estaría muy agradecido por cualquier ayuda.

Gracias!

Actualización: Algunas personas han sugerido que puede deberse al tamaño del archivo, pero no es así. Durante mis pruebas, agregué un botón para alternar entre el uso de la versión incrustada y la versión descargada de exactamente el mismo archivo PNG. La única diferencia es que el embebido fue optimizado por 'pngcrush' durante la compilación. Esto hace un intercambio de bytes (de RGBA a BRGA) y la pre-multiplicación de alfa. (http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html)

Además, el rendimiento al que me refiero no es la descarga, sino la prestación. Superpongo la pintura personalizada en la parte superior de la imagen (anulando el método drawRect de UIView), y es muy agitada cuando el fondo es la versión descargada, y muy suave cuando es la versión integrada (y por lo tanto optimizada). De nuevo, es exactamente el mismo archivo. La única diferencia es la optimización, que espero poder realizar en la imagen en tiempo de ejecución, en el dispositivo, después de descargarla.

Gracias de nuevo por la ayuda de todos!

+0

no creo que debería estar tocando los datos originales mientras que la prestación PNG (después de la primera vez, por ejemplo), por lo que no se sabe muy ver cómo podría hacer una gran diferencia. Tal vez es el tamaño de la imagen, como sugiere Andrew Grant? –

+0

Es importante tener en cuenta que el proceso pngcrush-equivalent debería ejecutarse, aunque solo una vez, por lo que habría un impacto en el rendimiento en ese punto –

Respuesta

1

¿Está almacenando el png en el tamaño original de descarga? Si se trata de una imagen de gran tamaño, tardará mucho más tiempo en renderizarse.

+0

. Buena idea, pero la imagen descargada tiene exactamente el mismo tamaño y resolución que la incrustada . Como cuestión de hecho, es exactamente la misma imagen. –

2

En la superficie, parece que algo más está en juego aquí. Cualquier manipulación adicional de imágenes solo debería agregar tiempo hasta que se muestre en pantalla ...

¿Sería posible hacer que el servidor gzip las imágenes enviando el encabezado HTTP apropiado? (Si incluso ayuda mucho al tamaño del archivo, es.)

Usar temporalmente la fuente pngcrush también puede ser una buena prueba, solo para obtener algunas medidas.

+0

Gracias por su consejo; Creo que intentaré usar el pngcrush solo para probar el concepto. Descargar el archivo del servidor y mostrarlo es bastante rápido, y solo debe ocurrir una vez. Los problemas de rendimiento son cuando superpongo renderizaciones personalizadas encima de ese UIImage. –

+0

Hmm, debe ser toda esa estratificación adicional que está matando el rendimiento. ¿Es posible fusionar las imágenes superpuestas en una sola superposición? Actualmente, estoy haciendo algo similar con un JPG con una sola superposición PNG "cubierta", y el rendimiento es bastante bueno. –

+0

Bueno, el hecho es que el rendimiento es muy bueno cuando se usa la versión optimizada del gráfico, y muy pobre cuando se usa la versión descargada del mismo archivo. Es por eso que estoy convencido de que las capas no tienen nada que ver con eso. –

3

El hecho de que diga que "parece" 100 veces más lento indica que no ha realizado ningún experimento, pero adivinó (debe ser la optimización PNG), y ahora está yendo por un camino basado en una corazonada.

Debe pasar un tiempo para confirmar cuál es el problema antes de intentar resolverlo. Mi instinto dice que la optimización PNG no debería ser el problema: que afecta principalmente a la carga de imágenes, pero una vez que están en la memoria no importa en qué formato de archivo estaban originalmente.

De todos modos, deberías intentarlo Comparación de AB, obtenga su código para cargar un PNG optimizado desde otro lugar y vea cómo se compara, o haga una aplicación de prueba que solo haga un dibujo en los dos tipos de PNG. Una vez que hayas confirmado cuál es el problema, podrás averiguar si necesitas compilar pngcrush en tu aplicación.

+0

Heh, he hecho esa misma comparación. Tengo un botón de alternar que me permite intercambiar la imagen en pantalla entre la versión descargada y la versión integrada del mismo archivo PNG, y la diferencia es enorme. La optimización hace lo siguiente: http://tinyurl.com/6fnsmt –

1

Bueno, parece que una buena forma de hacerlo (ya que no se puede ejecutar pngcrush en el iPhone y esperar que para acelerarlo) sería realizar sus solicitudes a través de un proxy que ejecuta pngcrush. El proxy tendría una buena potencia de caballo para darte algo de ventaja sobre el dolor de 100x que sientes.

7

Ese enlace que publicó respondió su pregunta.

Durante el proceso de compilación, XCode procesa previamente su PNG para que esté en un formato que sea más amigable con el chip gráfico del iPhone.

Los png que no se hayan procesado así probablemente utilizarán una ruta de representación más lenta, una que trate con el formato no nativo y el hecho de que el alfa se debe calcular por separado para cada color.

Así que tiene dos opciones;

  1. Realice el mismo trabajo que pngcrush hace y canjee ordenar/pre-multiplicar alfa. La aceleración puede deberse a uno o ambos.

  2. Después de cargar su imagen, puede "crear" una nueva imagen a partir de ella. Esta nueva imagen debe estar en formato nativo del iPhone y, por lo tanto, debe funcionar más rápido. La desventaja es que podría tomar un poco más de memoria.

E.g.

CGRect area = CGRectMake(0, 0, width, height); 
CGSize size = area.size; 
UIGraphicsBeginImageContext(size); 

[oldImage drawInRect:area]; 

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
0

Usted dice que está dibujando en la parte superior de la imagen reemplazando el método de un UIView drawRect:. ¿Estás tratando de hacer algo de animación dibujando repetidamente toda la imagen con tus cosas personalizadas encima?

Puede obtener mejores resultados si coloca sus cosas personalizadas en una vista o capa separada, y deje que el sistema operativo trate de componer el resultado sobre el fondo. El sistema operativo solo actualizará las partes de la pantalla que realmente cambie, y no volverá a pintar toda la imagen con tanta frecuencia.

1

intento pincrush a trans el archivo PNG normal al archivo PNG aplastado

Cuestiones relacionadas