Quel format d'image est le plus efficace pour économiser de la mémoire? PNG, JPEG ou GIF?
graphics
graphics-programming
image
memory-efficiency
Tredecies Nocturne
la source
la source
Réponses:
"Mémoire" et "efficacité" sont des termes couramment mal utilisés. Je vais donc vous donner une réponse pour quatre éléments différents susceptibles d'affecter les performances de votre jeu.
Je vais trop simplifier beaucoup trop de choses pour le rendre bref et concis, mais il y a des tonnes d'inexactitudes dans ce texte ci-dessous, alors prenez-le avec une pincée de sel. Cependant, les principaux concepts doivent être compréhensibles.
Espace de rangement
C'est la taille que vos images consomment sur votre distribution de logiciel. Plus vos ressources consomment d'espace, plus le téléchargement (à partir de votre site Web) sera long . Si vous distribuez sur des supports physiques, tels que des CD ou des DVD, vous devrez probablement procéder à de sérieuses optimisations à cet égard.
En général, JPEG compresse le mieux pour les photographies et les images sans bordures nettes. Toutefois, la qualité de vos images sera dégradée, car JPEG utilise une compression avec perte (vous pouvez ajuster le niveau de compression / dégradation lors de l'exportation d'images au format JPEG. Pour plus d'informations, reportez-vous à la documentation de votre logiciel de traitement d'images).
Cependant, aussi bon que soit le format JPEG, il ne prend pas en charge la transparence . Cela est crucial si vous souhaitez que les images apparaissent à travers d'autres personnes ou si vous souhaitez des images aux formes irrégulières. Le format GIF est un bon choix, mais il a été largement remplacé par le format PNG (il n’ya que peu de choses que le format GIF prend en charge mais pas du tout dans la programmation de jeux).
Le format PNG prend en charge la transparence (et la semi-transparence), compresse les données sans dégradation de la qualité (c’est-à-dire qu’il utilise la compression sans perte) et compresse assez bien, mais pas autant que le format JPG.
Le problème se pose lorsque vous avez besoin d'une bonne compression, ainsi que de la transparence. Si les images légèrement dégradées ne vous dérangent pas, vous pouvez utiliser des programmes de quantification PNG tels que pngquant , que vous pouvez tester en ligne sur TinyPNG . Gardez à l'esprit que la dégradation d'image réalisée par la quantification est différente de celle du JPEG (qui inclut la quantification ainsi que d'autres techniques agressives), assurez-vous donc d'essayer les deux, avec une grande variété de réglages.
Si vous souhaitez minimiser de manière agressive la taille de votre distribution, vous pouvez traiter manuellement chaque image comme suit:
Conseil: vous pouvez stocker des images dans un format et d'autres dans un autre format.
Il existe d'autres formats spécialisés tels que DXT, ETC et PVRTC. Ils prennent en charge la compression et peuvent également être chargés compressés en mémoire, mais ils ne sont pris en charge que par des GPU spécifiques. La plupart de ces GPU ne prennent en charge qu’un d’eux. Ainsi, à moins que vous ne connaissiez les spécifications matérielles exactes de votre matériel cible (un cas notable est: iPhone / iPad, qui prend en charge les textures PVRTC), évitez ces formats.
Programme mémoire
Je l'ai inclus ici, car c'est ce que l'on appelle couramment "mémoire". Cependant, si votre jeu utilise l’accélération graphique (et si vous créez un jeu après 1998, c’est le cas), la seule chose qui consomme de la mémoire sont vos descripteurs de texture (quelques octets par image), qui effectué par la quantité d’images, et non par leur taille ou leur format (quelques mises en garde, mais la plupart du temps sans importance).
Si votre plate-forme ne dispose pas de mémoire vidéo dédiée, ne fait pas l'objet d'une accélération matérielle ni d'autres cas inhabituels, la section suivante relative à la mémoire VRAM se déroulera totalement ou partiellement dans la RAM, mais les principes fondamentaux seront les mêmes.
Mémoire vidéo
C’est là que vos images seront stockées une fois votre programme exécuté. En général, le format dans lequel vous les avez stockées ne fera aucune différence, toutes les images étant décompressées avant de les charger dans la mémoire vidéo.
Maintenant, la VRAM consommée par vos images sera approximativement
width * height * bitdepth
pour chaque image chargée dans la VRAM. Il y a quelques points à noter ici:La largeur et la hauteur dans lesquelles vos images sont stockées dans la VRAM ne correspondront pas nécessairement à celles de votre image d'origine. Certains GPU ne peuvent gérer que les textures de tailles 2, ce qui permet de stocker votre image 320x240 dans un espace de 512x256 de la mémoire VRAM, avec le gaspillage de la mémoire inutilisée. Parfois, vous n'êtes même pas autorisé à charger des textures avec des tailles qui ne sont pas des puissances de 2 (comme dans GLES 1.1).
Par conséquent, si vous souhaitez réduire l'utilisation de la mémoire VRAM, vous pouvez envisager de créer un atlas sur vos images et de les dimensionner avec une puissance de 2, ce qui présente également l'avantage de réduire le nombre de changements d'état de rendu lors du rendu. Plus sur cela plus tard.
La profondeur de bit est très importante. Habituellement, les textures sont chargées dans la VRAM au format ARGB 32 bits ou XRGB 32 bits, mais si votre matériel peut prendre en charge des profondeurs 16 bits et que la taille en bits de la mémoire ne vous gêne pas, vous pouvez réduire de moitié la quantité de VRAM consommée par chaque image. , ce qui peut être quelque chose d'intéressant à considérer.
Mais quoi que vous fassiez, le facteur le plus important pour déterminer la quantité de VRAM utilisée par votre jeu est la quantité d’images que vous avez dans la VRAM à un moment donné. C’est le nombre que vous voudrez probablement garder aussi bas que possible si vous voulez un jeu performant. Le chargement et le déchargement de textures dans la VRAM étant coûteux, vous ne pouvez pas charger chaque image à chaque fois que vous l'utilisez. Vous devez trouver un équilibre entre le préchargement des images que vous allez probablement utiliser et les décharger lorsque vous êtes sûr de ne plus les utiliser. Faire ce droit n'est pas trivial, et vous devez penser à votre propre stratégie pour votre jeu particulier.
Vitesse d'exécution
Même s'il ne s'agit pas de "mémoire", il est très lié à la performance dans les jeux. Dessiner des images coûte cher et vous voulez vous assurer que votre rendu s'exécute aussi vite que possible. Bien sûr, ici, le format n'a pas d'importance, mais il y a d'autres choses qui importent:
Taille de l'image (en fait, il s'agirait de "taille d'échantillonnage"): plus la région d'une image que vous allez dessiner est grande, plus le temps nécessaire pour la dessiner est long. Le rendu d’une grande image dans une petite partie de l’écran n’est pas très efficace. Il existe donc une technique appelée mipmapping , qui consiste à échanger de la VRAM pour obtenir une vitesse de rendu rapide, en stockant vos images plusieurs fois à différentes résolutions et en utilisant la plus petite qui puisse donner. vous la qualité requise à tout moment. Le mappage MIP peut être effectué lorsque les images sont chargées, ce qui affectera la vitesse de chargement et l'utilisation de la mémoire VRAM, ou lors du prétraitement (en stockant manuellement différentes versions de la même image, ou en utilisant un format prenant en charge le mipmapping, tel que DDS), ce qui affectera le stockage. l’utilisation de la VRAM, mais aura peu d’impact sur la vitesse de chargement.
Rendre les changements d'état. Vous voudrez probablement dessiner plusieurs images différentes sur l'écran en même temps. Cependant, le GPU ne peut utiliser qu’une seule image source à la fois (ce n’est pas vrai, mais je vous prie de bien vouloir rester ici avec moi). L'image actuellement utilisée pour le rendu est l'un des nombreux états de rendu , et elle est chère. Donc, si vous allez utiliser la même image plusieurs fois (rappelez-vous quand j'ai mentionné les atlas de texture ?), Vous remarquerez un énorme gain de performances si vous réutilisez une image autant que vous le pouvez avant de changer l'état de rendu et de commencer à utiliser une image. image différente (il existe d'autres états de rendu en dehors de cela, et le réglage précis de l'ordre dans lequel vous tracez vos éléments pour minimiser les changements d'état de rendu est une activité très courante lors de l'amélioration des performances d'un jeu)
Cependant , l'optimisation de l'utilisation des images est un sujet très complexe, et ce que j'ai écrit ici est un aperçu très large et simplifié de certains des facteurs à prendre en compte lors de l'écriture d'un jeu. Je pense donc que c'est mieux si vous restez simple. et n'optimisez que lorsque vous en avez vraiment besoin. La plupart du temps, l'optimisation prématurée est inutile (et parfois même préjudiciable), alors prenez-le doucement.
la source
setEnforcePotImages
, cela désactive l'application de la puissance de textures de taille 2 pour OpenGLES 1.0. Ce n'est pas une bonne idée, car tout le matériel ne prend pas en charge les textures non puissantes. OpenGLES 2.0 nécessite la prise en charge des textures non puissantes, de sorte que si vous ciblez 2.0, vous pouvez utiliser des textures de toute taille. Pour plus d'informations, reportez-vous à la documentation de libgdx.Une fois qu'une image est chargée à partir du disque et formatée pour le rendu, elle utilisera la même quantité de mémoire, que cette image ait été enregistrée sur le disque au format PNG, JPEG ou GIF.
Règle générale: JPEG est un format avec perte qui dégradera la qualité de l’image afin de réduire la taille de l’image sur le disque. Le format PNG, en revanche, est un format d’image sans perte, ce qui entraîne généralement une plus grande taille des fichiers sur le disque. Le format GIF est également techniquement un format sans perte, mais il ne prend en charge que 256 couleurs maximum par image. Par conséquent, une image haute couleur entraîne souvent une lourde perte de qualité si elle est enregistrée au format GIF.
Ce n'est que pour leur représentation sur disque, cependant. En mémoire, ils développeront tous les deux le même format de texture, en utilisant la même quantité de mémoire, que vous les ayez enregistrés sur le disque au format PNG, JPEG ou GIF.
la source
Ça dépend.
Jpeg est le plus efficace pour les photographies. Ce n'est pas sans perte, mais les artefacts introduits par la compression sont moins visibles dans ce cas d'utilisation.
Le format PNG est sans perte et plus efficace pour les pixel-art avec des lignes nettes et peu de couleurs. Il prend également en charge la transparence alpha.
Le format GIF ne peut rien faire Le PNG ne peut pas faire mieux, à l'exception de sa capacité à stocker des animations. Mais cela n’est pertinent que dans le contexte des applications Web. En développement de jeu, vous créez généralement des animations à l'aide d'un tableur.
Notez que lorsque vous utilisez un moteur graphique tel que Libgdx, il sera probablement décompressé les images juste après leur chargement, puis conservé en mémoire sous forme de valeurs RGBA non compressées. Ainsi, le format de l'image n'a d'importance que pour la vitesse de chargement et dispose d'un espace disque (ou d'une utilisation de la bande passante lorsque vous les envoyez sur le net).
la source
Je ne connais pas grand chose de libgdx, mais des formats d’image et des graphiques:
JPEG est très bon dans les cas de photos du monde réel. Elles entraînent des pertes, mais vous ne verrez pas d'artefacts sur les photos, sauf si vous prenez des photos avec des bords nets avec des espaces colorés, tels que du texte écrit ou des bandes dessinées. Utilisez-les pour les grands graphiques d'arrière-plan.
GIF est obsolète, il ne peut stocker que des couleurs palettisées (jusqu'à 8 bits par pixel) avec une couleur dédiée pour une transparence complète. Il permet de petites animations basées sur des cadres. Il était une fois un brevet sur son algorithme d'empaquetage afin qu'il ne puisse pas être utilisé partout légalement. À cause de ce brevet, PNG a été développé.
Le format PNG est plus ou moins un bitmap compressé pouvant stocker des formats de pixels RVB + alpha (jusqu’à 32 bits) et autres. Il est spécialisé dans la décompression rapide de petites parties de cette image, ce qui est pratique pour les appareils très petits et lents (comme un téléphone portable de 10 ans), mais les bibliothèques actuelles ne font que les décompresser en bitmaps lors du chargement.
Le format PNG est meilleur que le format GIF en termes de taille, de rapidité et de fonctionnalités, mais si vous souhaitez stocker efficacement les bitmaps, je vous conseillerais: que .PNG. [/ edit])
PNM / PBM / PGM / PAM sont des formats bitmap simples avec des en-têtes KISS en texte brut. L'utilisation de gzip sur ceux-ci donnera une taille de fichier similaire à celle du fichier PNG. Bzip2 est donc la meilleure solution pour cela. Si vous souhaitez utiliser des bitmaps en interne dans votre programme, vous pouvez utiliser des bitmaps compressés bzip2 dans un conteneur .tar ou .zip. Si vous n'avez pas bzip2, utiliser des fichiers PNM dans un conteneur zip (zip avec compression maximale) peut être similaire à utiliser des fichiers PNG. - Ainsi, le stockage des fichiers PNG dans un fichier ZIP n’a que peu d’avantages, voire aucun avantage - cela augmenterait probablement le temps nécessaire au chargement de l’image.
En outre, il est judicieux de stocker plusieurs images-objets / images-sprites dans une même image, en particulier si vous en avez besoin dans la même situation.
la source
En tant que format de stockage, JPEG est probablement le meilleur choix pour certaines textures telles que l'herbe ou les murs, où la perte d'informations est probablement indétectable. Suivi par PNG lorsque vous avez besoin de transparence ou lorsque vous ne pouvez pas payer avec perte d’informations, par exemple des sprites dans un jeu en 2D (le joueur, des ennemis, un coffre au trésor), vous voudrez probablement utiliser PNG pour ces images.
En ce qui concerne les coûts de mémoire, le format utilisé pour stocker les graphiques de jeu dans le système de fichiers n’a aucune pertinence. Que vous stockiez des tampons de pixels dans la mémoire VRAM ou RAM (logiciel de rendu logiciel), vous les avez probablement stockés non compressés, car les jeux favorisent la lecture rapide des pixels par rapport à la mémoire utilisée par chaque tampon de pixels.
Les données compressées stockées en mémoire n'ont aucun sens si ce n'est que vous conservez une sorte de cache pour enregistrer les lectures sur disque, mais vous devez probablement lire à partir de ce cache dans un état non compressé pour les images utilisées à un moment donné de votre jeu.
Les données d'image comprimées ont un peu plus de sens si un décodage matériel rapide était possible. Pour le mappage normal au moins, je me souviens de ce http://en.wikipedia.org/wiki/3Dc . Avec cela, vous pouvez économiser de la VRAM. Je ne connais pas encore d'autres exemples de décodage matériel.
En résumé: quels que soient les formats utilisés par votre jeu pour stocker les graphiques dans un stockage persistant, vous devrez le décoder et conserver une version non compressée en mémoire dynamique, en mémoire vidéo ou les deux, afin de pouvoir les restituer rapidement en cas de besoin.
Enfin: je suis un gars de bureau. Quand je dis "mémoire", je me réfère toujours à la mémoire dynamique. Quand je dis "disque", "système de fichiers" ou "stockage persistant", je me réfère toujours à tout ce que votre périphérique utilise comme stockage persistant, généralement, je pense, sur des disques durs. Lorsque vous avez dit "efficacité de la mémoire", je l'ai pris pour "mémoire dynamique" et non pour "stockage persistant". Dernièrement, je vois beaucoup de gens utiliser le mot "mémoire" pour parler de "stockage persistant" (peut-être que la terminologie des appareils mobiles?).
la source