Facebook LinkedIn SourceForge Twitter RSS LastFM
logologo

Estimer la consommation mémoire des ressources GD

Geoffray Warnants|13/11/2010|5 commentaires

La librairie GD forme aujourd'hui avec PHP un couple apprécié des développeurs web. Elle offre en effet un accès d'une grande simplicité aux traitements d'images, ces opérations obscures qu'on sait truffées de formules mathématiques et autres transformations matricielles, et qu'on devine par conséquent probablement gourmandes en ressources matérielles. Mais sait-on exactement jusqu'à quel point ? Pour ma part non, jusqu'à aujourd'hui...

Le graphique ci-dessous représente la quantité de mémoire vive consommée par un script lors de la création d'une ressource GD en fonction des dimensions de l'image traitée (ou plutôt de sa définition pour être exact)

Mémoire allouée par GD selon la définition de l'image (GD bundled v2.0.34)

Comme on pouvait s'en douter, la mémoire requise est proportionnelle au nombre de couleurs ainsi qu'aux dimensions de l'image. On peut donc envisager qu'un fichier suffisamment imposant puisse saturer complètement la mémoire libre, celle-ci n'étant pas illimitée. Il en résultera alors un arrêt brutal du script causé par une erreur fatale (Fatal error: Allowed memory size of %d bytes exhausted (tried to allocate %d bytes)). Un sombre scénario qui, pour pouvoir être évité, doit d'abord être anticipé.

L'objectif de cette étude est donc d'estimer les dimensions maximales approximatives acceptables selon la configuration mémoire en vigueur. J'insiste sur le caractère approximatif car j'ai pu constater qu'à définition égale, la mémoire occupée par une ressource GD dépend aussi de ses proportions. Ainsi une image au format "portrait" (plus haute que large) risque de nécessiter d'avantage de mémoire que la même au format "paysage". Heureusement cette différence ne concerne de manière significative que des images étirées à l'extrême.

Voici donc les dimensions maximales estimées pour des images au format 4/3 :

memory_limit imagecreatetruecolor imagecreate
64M 13 Mpx (~4162x3123) 32 Mpx (~6532x4899)
128M 26 Mpx (~5889x4415) 65 Mpx (~9308x6983)
256M 53 Mpx (~8406x6305) 128 Mpx (~13064x9798)
512M 106 Mpx (~11887x8917) 262 Mpx (~18689x14019)
1G 201 Mpx (~16372x12277) 514 Mpx (~26179x19634)

Ces valeurs permettent alors d'instaurer des vérifications adaptées aux contraintes mémoire en vigueur. Par exemple :

<?php
ini_set('memory_limit', '64M');
$size = getimagesize($filename);
if ($size===false || $size[0] > 4000 || $size[1] > 3000) {
    throw new Exception('Image too large');
}
$rc = imagecreatetruecolor($filename);

Notons ici que le choix de la fonction getimagesize n'est pas anodin : elle permet d'obtenir les dimensions du fichier sans le charger entièrement en mémoire, ce qui n'est pas le cas par exemple de ses homologues imagesx et imagesy qui risquent de provoquer la saturation mémoire avant même d'avoir pu s'en prémunir...

Conclusion

La consommation mémoire des ressources GD n'est finalement pas si excessive. Les configurations standards permettent déjà de manipuler des images importantes sans soucis. Evidemment, je ne vous apprends rien en répétant que tout fichier externe doit être considéré comme une source de données potentiellement à risque, ce qui est d'autant plus vrai pour les images reçues par exemple au travers d'un formulaire d'upload, et qu'elles doivent donc toujours faire l'objet d'un contrôle minutieux avant d'être manipulées. Car une gestion correcte de la mémoire est avant tout du bon ressort du programmeur.

<<< Retour

Réagir à cet article

*


(Ne sera pas publiée, servira uniquement à afficher votre gravatar)


(Lien en dur et dofollow)

zend framework