Le trimming

📅 June 06, 2023

Que l'on fasse un jeu ou une application, la gestion des assets est importante. Optimiser ses images peut alors soulager l'appareil de l'utilisateur et rendre votre application plus rapide.

Je commence une série d'articles sur les bases dans la gestion d'assets dans le jeu 2D. Je reçois encore très souvent des images non rognées, c'est dommage tant il fait perdre du temps à tout le monde. Le trimming est vraiment l'une des premières optimisations fastoches. 👇

Qu'est ce que le trimming

Le trimming, ou l'art de rogner, consiste à supprimer la partie transparente autour de son sprite.

image d'origine

Cela permet de réduire la dimension de l'image et donc cela a pour effet :

  • de réduire sa taille sur le disque dur 🌱
  • de diminuer la RAM utilisée dans votre jeu 🚀
  • d'accélérer le temps de décodage et de transmission au GPU 🚝
  • d'accélérer le rendu sur votre écran en diminuant l'overdraw 🚝
  • de diminuer le temps de chargement dans votre jeu si c'est sur un serveur 🌱
  • et par ricochet : moins d'électricité utilisée 🌱

Et tout ça grâce à quelques pixels en moins !

Le tableau suivant récapitule les gains sur une seule image :

Image Dimensions Taille Temps de chargement (local / 4G / 3G) RAM1 GPU elapsed2
Raw image d'origine 1024x1024 7.7kB 2ms / 59ms / 749ms 4Mo 118µs
Trimmed image trimmed 300x380 3.9kB 2ms / 58ms / 657ms 0.43Mo 47µs

On peut visualiser ici l'overdraw sur les deux images grâce à Intel Graphics Frame Analyser. On voit bien que le GPU travaille inutilement. Certes sur seulement 2 images ce n'est pas bien grave mais à l'échelle d'un jeu ou d'une application c'est autre chose.

graphics analyzer test
Affichage des 2 images
graphics analyzer test overdraw
Overdraw

Les exceptions

Toutefois, dans le process de création d'image jusqu'à son utilisation finale dans un jeu, il peut être utile d'avoir un espace transparent autour de son sprite. Cela peut en effet servir au placement de l'image, mais n'a de sens que pour le placement de sprites d'une même animation ou bien d'un bouton à plusieurs états afin d'éviter de manuellement replacer chaque frame. En effet, quand on rogne une séquence d'images, celles-ci peuvent ne plus avoir la même dimension, et nous perdons ainsi le référentiel d'assemblage.

Et ainsi nous pourrions nous retrouver avec une animation comme celle de droite dans le tableau suivant. Certes, il serait facile de replacer les frames de cet exemple manuellement, mais on n'a pas toujours une animation aussi simple avec un pivot calé en bas à droite de l'image... Nous verrons bientôt comment conserver ces données pour optimiser vos images (dans un prochain article promis 👀).

Séquence de PNG de dimensions identiques PNG trimmés nécessitant un repositionnement manuel

ℹ️ animation par RTFX

Comment trimmer sans trimer

Avec Affinity Photo, il suffit de faire Document > Attacher le Canvas. Pour Photoshop, il faut faire Image > Rognage et bien cocher pixels transparents sur tous les bords.

Supprimer le contour transparent avec Affinity Photo

Que ce soit sur Affinity ou Photoshop, on peut batcher avec respectivement Fichier > Nouveau traitement par lot et Fichier > Automatiser > Batch en utilisant une macro/script (💾 macro affinity pour rogner). On peut également utiliser une interface de ligne de commande comme ImageMagick: magick profile-pic-uber.png -trim trimmed-with-magick.png

Enfin, le mieux reste d'éviter tout ça dès le processus d'export depuis votre éditeur préféré.

🎨 Pour les artistes Dans l'idéal on préfèrera exporter sans transparence autour de son sprite, à moins que l'image appartienne à une séquence de PNG et que cette "information" soit nécessaire au placement des sprites.


  1. j'ai relevé la variable GPU Time Elapsed sur une app native Windows des fonctions d'écriture GPU à l'aide du logiciel Intel Graphics Frame Analyser
  2. RAM théorique : width * height * 32 / 8 / 1024 / 1024 pour les PNG