IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    février 2013
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : février 2013
    Messages : 114
    Points : 80
    Points
    80
    Par défaut Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes)
    Bonsoir,

    Voici un code qui avec la bilbi GD, ouvre une image N&B (du 400 DPI en A4, soit à peu près 3300/4700 pixels si mes souvenirs sont bons), détecte les formes les plus grandes (+ de 3500 pixels), les colorie en blanc, et sauvegarde le résultat sous une nouvelle image :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    <?php
     
    	function hashh($arg1, $arg2)
    	{
    		$sum = $arg1 + $arg2;
        		return $sum * ($sum + 1)/2 + $arg1;
    	}
     
    	$image = imagecreatefrompng("step3-1.png"); 
      	$white = imagecolorallocate($image, 255, 255, 255);
      	$black = imagecolorallocate($image, 0, 0, 0); 
      	list($width, $height) = getimagesize("step3-1.png"); 
     
    	$allPixels = array();
     
            for ($i=1; $i<$width; $i++) {
     
    		for ($j=1; $j<$height; $j++) {
     
    			if (imagecolorat($image, $i, $j) == 0) // si pixel noir..
    			{
    				$stack = array(
    					array($i, $j)
    				);
     
    				$localArray = array();
     
    				while (count($stack) > 0) { // pour chaque pixel noir voisin...
     
    					$current = array_pop($stack);
     
    					array_push($localArray, $current);
     
    					$allPixels[hashh($current[0],$current[1])] = true;
     
    					$north = array($current[0], $current[1]-1);
    					$south = array($current[0], $current[1]+1);
    					$west = array($current[0]-1, $current[1]);
    					$east = array($current[0]+1, $current[1]);
     
    					if ($north[0] > 0 && $north[0] < $width && $north[1] > 0 && $north[1] < $height)
    						if ((imagecolorat($image, $north[0], $north[1]) == 0) && !isset($allPixels[hashh($north[0],$north[1])]))
    							array_push($stack, $north);
     
    					if ($south[0] > 0 && $south[0] < $width && $south[1] > 0 && $south[1] < $height) 
    						if ((imagecolorat($image, $south[0], $south[1]) == 0) && !isset($allPixels[hashh($south[0],$south[1])]))
    							array_push($stack, $south);
     
    					if ($west[0] > 0 && $west[0] < $width && $west[1] > 0 && $west[1] < $height) 
    						if ((imagecolorat($image, $west[0], $west[1]) == 0) && !isset($allPixels[hashh($west[0],$west[1])]))
    							array_push($stack, $west);
     
    					if ($east[0] > 0 && $east[0] < $width && $east[1] > 0 && $east[1] < $height) 
    						if ((imagecolorat($image, $east[0], $east[1]) == 0) && !isset($allPixels[hashh($east[0],$east[1])]))
    							 array_push($stack, $east);
     
    				}
     
    				  if (count($localArray) > 3500) {
     
    					$rand = imagecolorallocate($image, 255, 255, 255); 
     
    					for ($n=0; $n<count($localArray); $n++) {
     
    						imagesetpixel($image, $localArray[$n][0], $localArray[$n][1], $rand);
    					}
    				}
    			}
    		}
    	}
     
     
    	imagepng($image, './result.png');
     
     
    ?>
    Je ne me représente pas bien ce que consomme ce code en terme de mémoire, m'enfin je me dis qu'un VPS de 2 Go de ram peut quand même exécuter ces quelques lignes. Pourtant j'obtiens de manière aléatoire une erreur mémoire :

    Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 83886080 bytes) in bla bla bla
    Le problème, c'est que c'est aléatoire Y a-t-il des fuites de mémoire dans ce code, et si oui, où ? Si non, comment se passer de ces erreurs intempestives ?

    Merci
    "There should be no boundaries to human endeavor" - Hawking
    Retrouvez moi sur GitHub : https://github.com/JeanLouisMassei

  2. #2
    Expert éminent

    Homme Profil pro
    Développeur Web
    Inscrit en
    septembre 2010
    Messages
    5 099
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : septembre 2010
    Messages : 5 099
    Points : 9 801
    Points
    9 801
    Par défaut
    Citation Envoyé par MrPchoun Voir le message
    Je ne me représente pas bien ce que consomme ce code en terme de mémoire
    Je ne suis pas en mesure de vérifier ton code car la lib GD demande un certain temps pour s'y plonger et on ne fait pas ça tous les jours. Cela dit, la consommation peut être retournée avec memory_get_peak_usage() et la mémoire disponible avec ini_get('memory_limit').

    Ces deux nombres ne seront pas directement comparables car memory_get_peak_usage() retourne un nombre d'octets non formaté. Tu peux utiliser une fonction de conversion pour avoir un nombre plus lisible :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    	function formateOctets ($octets,$espace='',$type=true)
    	{
    		// Retourne une chaine formatée depuis un nombre d'octets (8912896 -> 8.5 Mo)
    		// Ne pas utiliser intval pour compatibilité php5 sur les très grands nombres
    		$octets = is_numeric($octets) ? $octets : 0;
    		$type = trim($type) != false ? 'o' : null;
     
    		$unite = ["", "K", "M", "G", "T", "P", "E", "Z", "Y"];
    		$index = 0;
    		$max_index = count($unite) - 1;
     
    		while($octets >= 1024 && $index < $max_index)
    		{
    			$octets /= 1024;
    			$index++;
    		}
    		$octets = $index < 3 ?  round($octets,1) : round($octets,3);
     
    		return($octets.$espace.$unite[$index].$type);
    	}
     
            echo 'Mémoire utilisée: '.formateOctets (memory_get_peak_usage()).', mémoire disponible: '.ini_get('memory_limit').'o';

    Sinon dans ton code la fonction imagepng possède un troisième paramètre pour régler la qualité. Peut être tu pourrais essayer de la baisser pour voir si ça consomme moins.

    Et enfin si tu n'arrives pas à éviter ces erreurs pour certaines images tu peux utiliser register_shutdown_function pour gérer l'erreur fatale et retourner un message personnalisé pour le visiteur plutôt que rien ou la page d'erreur de php. C'est ce que j'utilise dans ce module d'upload pour le traitement (optionnel) d'images à la volée lors du téléchargement d'images vers le serveur.

Discussions similaires

  1. Réponses: 3
    Dernier message: 08/12/2009, 15h14
  2. Réponses: 1
    Dernier message: 03/10/2009, 12h36
  3. [PEAR][Mail] Fatal Error : Allowed memory size of 8388608 bytes exhausted
    Par bigben89 dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 20/10/2008, 19h01
  4. Réponses: 3
    Dernier message: 08/08/2007, 20h08
  5. [Librairies] zip.lib.php Fatal error: Allowed memory size of 8388608 bytes exhausted
    Par manaboko dans le forum Bibliothèques et frameworks
    Réponses: 9
    Dernier message: 22/05/2006, 11h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo