vendredi 27 janvier 2012

iPhone «optimisé» PNG

Pour la plupart, de la documentation développeur d'Apple pour Mac et iPhone est excellente. Ils sont bien écrits, précis et fournir des exemples de code excellente. Il ya, bien sûr, toujours des lacunes, en particulier avec les nouveaux domaines. Parfois, ces écarts sont simplement une question de contraintes de ressources, le volume de la documentation les équipes doivent maintenir la documentation est stupéfiante, et les cadres sont constamment ajoutés et mis à jour.

D'autres fois, Apple est peu loquace à propos de choses non pas parce que des contraintes de ressources, mais plutôt intentionnellement, si ce n'est pas toujours bien pourquoi. Voulez-vous savoir à quelle vitesse le processeur de votre iPhone est, ou combien de mémoire est disponible à votre demande? Ces deux sont évidemment pertinentes pour le développement pour l'iPhone, mais ne regardez pas à Apple pour cette information. L'information est disponible (processor | memory), Mais pas par Apple.

Voici un autre domaine où Apple est moins bien paraître: Quand il s'agit d'utiliser l'iPhone d'images PNG, Apple vous dit que Xcode "optimise" PNG dans le cadre du processus de construction et, par conséquent, vous devriez toujours utiliser des images PNG dans vos projets iPhone. Les images PNG sont généralement plus grandes que les fichiers JPEG, ce qui provoque votre application soit un peu plus grand, mais vous serez récompensé par une sorte mystérieuse de l'amélioration.

Puisque cette information n'est pas documentée, ce qui suit est quelque chose d'une supposition éclairée basée sur la recherche et des observations. Je serai heureux de corriger sur toute inexactitude, alors n'hésitez pas à me ping si vous voyez quelque chose de mal.

Donc, juste quelle est cette magie, le mystère «optimisation»?



Pendant la construction, Xcode essentiellement vis de votre image PNG, le transformant en quelque chose qui techniquement n'est plus une image PNG. Xcode ne modifie pas votre fichier original, mais quand il le copie dans le dossier Resources de votre paquet de demande, ce qu'il fait est qu'il byte-échange les octets en rouge et bleu et aussi "premultiplies l'alpha" (si cela ne fait pas sens, ne vous inquiétez pas, nous en parlerons dans un instant). L' PNG spécifications ne supporte pas non plus de ces changements, ce qui explique pourquoi l'image n'est plus techniquement un PNG et ne peut pas être chargé par la plupart des logiciels de retouche d'image. Non pas que ce qui importe vraiment, puisque la nouvelle version existe seulement à l'intérieur de votre paquet d'application, mais cela signifie que tout fichier PNG que vous incluez dans votre bundle soft ne devrait pas être, par exemple, FTPed ou par courriel à partir de votre application directement, parce que le fichier sera corrompu dans la mesure où la plupart des logiciels sont concernés.

Échange d'octets


Byte swap est exactement ce que cela ressemble. Images de synthèse non compressé graphiques sont les plus souvent stockés en séquences de trois ou quatre octets, ou "octets" représentant chaque pixel de l'image. Chaque octet dans le pixel représente l'une des trois couleurs primaires additives (rouge, bleu et vert), plus il ya souvent un autre octet appelé «alpha», que nous allons examiner dans un instant. Il ya d'autres manières de stocker des images, mais c'est la technique la plus courante. Le plus commun des octets de commande utilisés dans cette technique est RVB (ou RGBA) qui signifie rouge-vert-bleu (-alpha). Cela signifie qu'un pixel est représenté en mémoire par quatre octets, le premier représentant de l'intensité du rouge, la seconde représentant l'intensité du vert, et le troisième représentant l'intensité du bleu (nous ignorerons alpha pour l'instant). La spécification PNG utilise cet octet de commandes, comme le font de nombreux formats d'image.

Cependant, la mémoire vidéo de l'iPhone utilise un octet de commande non-standard de BGR ou bleu-vert-rouge (je ne crois pas qu'il ya une composante alpha dans VRAM de l'iPhone). Pour copier à partir d'une image en mémoire en utilisant RGBA à la mémoire vidéo en utilisant la BSG est plus coûteux que de simples calculs à partir de copier, par exemple, BGR BGR, qui peut être fait avec un seul, déplacer de la mémoire rapide (ou «blit») opération. En faisant cela, byte-swap dans la copie de fichiers Phase de construction, votre demande est (dans certaines situations) capable d'ignorer la composante alpha lors du chargement du fichier dans la mémoire de sorte qu'il peut utiliser l'opération mémoire plus rapide déplacer pour obtenir l'image dans la mémoire vidéo ( et donc sur l'écran).

Alpha prémultipliées


Okay, c'est logique, mais que dire de ce "multipliant à gauche de l'alpha" chose? Que l'on sorte de sons mystérieux, n'est-ce pas? Comme mentionné dans la section précédente, VRAM de l'iPhone n'a pas de composante alpha, donc si nous allons à ignorer cette composante, nous avons encore besoin de le prendre en compte une certaine manière. Rappelez-vous que les images PNG qui ont été optimisés pour l'iPhone sont stockées sous forme de quatre valeurs, représentant le Bleu, Vert, Rouge, et des composants Alpha (dans cet ordre). Bien qu'il soit appelé un "composant", Alpha n'est pas vraiment une composante de couleur du tout. C'est plus comme un modificateur qui agit sur les trois autres valeurs, et elle représente la quantité de tout ce qui est sous la couleur va montrer à travers. Ainsi, une couleur qui ressemble à ceci:

B:1.0
G:0.0
R:0.0
A:0.5

Représenterait la couleur bleue, mais avec une opacité de 50%. Pour que l'ordinateur pour utiliser le composant alpha, il doit multiplier les temps de l'alpha des trois autres composantes (et éventuellement par d'autres valeurs) avant de les mettre en mémoire vidéo. Ce processus de multiplication est plus coûteux en calcul de simplement copier la valeur dans la mémoire vidéo. Ainsi, Xcode premultiplies aussi l'alpha par les trois composantes et stocke la valeur multipliée. En conséquence, la couleur ci-dessus ressemblerait à ceci après que les fichiers de copie Phase de construction:

B:0.5
G:0.0
R:0.0
A:0.5

Notez que la composante bleue dans ce nouveau pixel est égale à la composante bleue de la version précédente, multiplié par l'alpha. Le résultat de cette prémultiplication, est que la composante alpha peut être ignoré lors du chargement de l'image dans la mémoire et l'image peut alors être placés directement sur la mémoire vidéo sans avoir à faire de coûteuses en virgule flottante multiplications pour calculer l'alpha. Eh bien, au moins, parfois. Ce pixel est ce que le pixel ressemblerait quand il est dessiné sur fond blanc.

Alors, qu'advient-il si il ya une couleur sous qui doit montrer à travers? C'est là que les choses peuvent devenir un peu déroutant. Si votre demande est le dessin de l'image sur le dessus de quelque chose d'autre, ou si vous êtes en utilisant le canal alpha dans l'image comme un masque, puis l'iPhone ne peut pas utiliser cette optimisation. Il a pour faire les calculs alpha (c'est pourquoi le canal alpha est laissé intact dans la multiplication de pré-traitement), le byte-swapping l'offre encore quelques améliorations. Pour la plupart, vous ne devez pas vous inquiéter à ce sujet - tout se passe sous le capot. La seule chose que vous devriez prendre loin de lui cependant, c'est que vous pouvez aider votre iPhone savoir quand il est sécuritaire d'utiliser l'optimisation. La façon de faire est de vous assurer que vous cochez la case "opaque" case à cocher dans Interface Builder pour votre point de vue image, ou d'autres vues qui contiennent des images, ou définir la propriété opaques de votre UIImageView à YES dans le code. Ceci indique l'iPhone qu'il est sécuritaire d'effectuer l'opération plus rapide blit et ignorer le canal alpha parce que rien ci-dessous montre à travers un objet opaque et il n'y a aucun besoin de faire des calculs flottants onéreux Point Alpha pour cet objet. Bien sûr, si vous utilisez le canal alpha de votre image, ou si vous faites des compositions d'images complexes dans votre application à l'exécution, vous ne devriez pas faire le point de vue opaque. Mais, si vous êtes simplement l'affichage d'une image dans une UIImageView, en vérifiant que la case opaque est une idée vraiment, vraiment bon.

Énormément de temps, des images PNG ont 1,0 pour la valeur alpha dans chaque pixel. En conséquence, plus souvent qu'autrement, le programme fonctionne plus rapidement et utiliser moins de mémoire à cause de la PNG "optimisations" fait par Xcode.

Qu'advient-il lorsque vous utilisez différents types de fichiers


Lorsque vous utilisez un autre type de fichier (ou si vous chargez un fichier non optimisés PNG), votre iPhone doit faire le byte-swapping et prémultiplication alpha à la charge en temps (et éventuellement refaire la multiplication alpha à l'affichage en temps). Votre demande a essentiellement pour faire le même traitement que Xcode fait, mais c'est de le faire au moment de l'exécution au lieu de construire des temps. Cela va vous coûter tant en termes de cycles de processeur et de mémoire supplémentaire. Une des raisons pour lesquelles Safari Mobile est le plus gros du porc de la mémoire de l'intégré dans les applications iPhone c'est parce que les images qu'il a à charge pour l'affichage des pages web sont toutes les images non optimisés, pour la plupart des fichiers JPEG. Depuis JPEG est un format compressé, il a ajouté l'étape supplémentaire d'avoir à décompresser l'image dans la mémoire avant de pouvoir faire le prémultiplication et byte-swapping.

Aucun commentaire: