begin process at 2008 07 25 13:05:24
1 216 226 membres
190 nouveaux aujourd'hui
14 180 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

CLASSE DE TRAITEMENT D'IMAGE


Information sur la source

Catégorie :Graphique Classé sous : image, redimensionnement, recadrage Niveau : Initié Date de création : 09/04/2008 Vu / téléchargé: 3 645 / 213

Note :
9 / 10 - par 2 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (22)
Ajouter un commentaire et/ou une note

Description

Cette classe permet diverses opérations sur les images.
Vous pourrez entre autres :

- Redimensionner
- Recadrer
- Ajouter un logo
- Ajoute du texte
- Ajout d'effets tels que flou, contrast, luminosité ...
- Sauvegarde ou affichage de l'image.

Le zip comprend une police pour l'écriture sur image ainsi qu'un fichier d'exemple.

Source

  • <?php
  • /**
  • * Classe ImgTraitement
  • *
  • * Class De traitement d'image
  • * <code>
  • * $img = new Imgtraitement('nen.jpg');
  • * $img->resize(320,0);
  • * $img->save('test2.jpg');
  • * </code>
  • *
  • * @version 1.1.0
  • * @author Olivier ROGER <>
  • *
  • *
  • */
  • class ImgTraitement
  • {
  • /**
  • * @access private
  • * @var int
  • */
  • private $width;
  • /**
  • * @var int
  • * @access private
  • */
  • private $height;
  • /**
  • * Type de l image : 1 = gif ; 2 = jpeg; 3= png
  • * @var string
  • * @access private
  • *
  • */
  • private $type;
  • /**
  • * @var string $mime Type mime de l image
  • * @access private
  • */
  • private $mime;
  • /**
  • * @var img Fichier image source
  • * @access private
  • */
  • private $source;
  • private $copie;
  • /**
  • * @var string Police d'ecriture selectionnee. Defaut verdanna.
  • * @access private
  • */
  • private $font;
  • /**
  • * @var ressource Couleur choisi (par defaut bordeau)
  • * @access private
  • */
  • private $couleur;
  • /**
  • * @var ressource autre image a coller sur l image d origine
  • * @access private
  • */
  • private $logo;
  • /**
  • * @var ressource Largeur du logo
  • * @access private
  • */
  • private $widthL;
  • /**
  • * @var ressource Hauteur du logo
  • * @access private
  • */
  • private $heightL;
  • /**
  • * @var ressource Type du logo
  • * @access private
  • */
  • private $typeL;
  • /**
  • * @var array Info de l'image
  • * @access private
  • */
  • private $infoImage;
  • /**
  • * @var int Poids de l'image
  • * @access private
  • */
  • private $poids;
  • /**
  • * Construteur
  • */
  • public function __construct($img)
  • {
  • if(!empty($img) && file_exists($img))
  • {
  • $info = getimagesize($img);
  • $this->width = $info[0];
  • $this->height = $info[1];
  • $this->type = $info[2]; // 1:gif; 2:jpg; 3:png; 4:swf; 5:psd; 6:bmp; 7:tiff
  • $this->mime = $info['mime'];
  • $this->copie = null;
  • $this->source = $this->createFromType($img);
  • if($this->source == false)
  • {
  • echo 'Format d\'image non supporté';
  • exit;
  • }
  • $this->couleur = imagecolorallocate($this->source,187,3,33);
  • $this->poids = filesize($img);
  • $this->infoImage = array();
  • $this->infoImage['extension'] = strchr($img, '.');
  • $this->infoImage['extension'] = substr($this->infoImage['extension'], 1); // Récupère l'extension après le .
  • $this->infoImage['extension'] = strtolower($this->infoImage['extension']);
  • }
  • }
  • /**
  • * Récupère les informations de l'image
  • * @access public
  • * @return array Information de l'image (reso,poids,extension,mime)
  • */
  • public function getInfo()
  • {
  • $this->infoImage['width'] = $this->width;
  • $this->infoImage['height'] = $this->height;
  • $this->infoImage['mime'] = $this->mime;
  • $this->infoImage['poids'] = round($this->poids/1024,2);
  • return $this->infoImage;
  • }
  • /**
  • * Ajoute une image en tant que logo
  • * @access public
  • * @param string chemin vers l'image
  • */
  • public function addLogo($logo)
  • {
  • list($this->widthL,$this->heightL,$this->typeL) = getimagesize($logo);
  • $this->logo = $this->createFromType($logo);
  • imagealphablending($this->logo,TRUE); // Activation de la transparence
  • }
  • /**
  • * Ajoute le logo à l'image principale
  • * @access public
  • * @param string $pos Position du logo : ct(centre),hg(haut gauche),hd,bg(bas gauche),bd(défaut)
  • * @param int $opacite % d'opacité du logo , par défaut 75
  • * @return bool
  • */
  • public function mergeLogo($pos='bd',$opacite=75)
  • {
  • if($pos =='hg')
  • {
  • $posX = 0;
  • $posY = 0;
  • }
  • elseif($pos=='hd')
  • {
  • $posX = ($this->width - $this->widthL);
  • $posY = 0;
  • }
  • elseif($pos == 'bg')
  • {
  • $posX = 0;
  • $posY = ($this->height - $this->heightL);
  • }
  • elseif($pos == 'bd')
  • {
  • $posX = ($this->width - $this->widthL);
  • $posY = ($this->height - $this->heightL);
  • }
  • elseif($pos == 'ct')
  • {
  • $posX = (($this->width/2) - ($this->widthL/2));
  • $posY = (($this->height/2) - ($this->heightL/2));
  • }
  • if(imagecopymerge($this->source,$this->logo,$posX,$posY,0,0,$this->widthL,$this->heightL,$opacite))
  • return true;
  • else
  • return false;
  • }
  • /**
  • * Créer une ressource image selon son type
  • * @access protected
  • * @param string image
  • * @return ressource image
  • */
  • protected function createFromType($img)
  • {
  • if($this->type==1)
  • $crea = imagecreatefromgif($img);
  • elseif($this->type == 2)
  • $crea = imagecreatefromjpeg($img);
  • elseif($this->type == 3)
  • $crea = imagecreatefrompng($img);
  • else
  • $crea = false;
  • return $crea;
  • }
  • /**
  • * Convertit l'image en niveau de gris. Imagefilter remplace les calcul via matrice. 10x plus rapide
  • * @access public
  • */
  • public function greyScale()
  • {
  • imagefilter($this->source,IMG_FILTER_GRAYSCALE);
  • }
  • /**
  • * Ajoute du flou à l'image. Imagefilter remplace les calcul via matrice. 10x plus rapide
  • * @access public
  • * @param int $factor Facteur de flou
  • */
  • public function blur($factor)
  • {
  • imagefilter($this->source,IMG_FILTER_GAUSSIAN_BLUR,$factor);
  • }
  • /**
  • * Ajoute du bruit à l'image. (relativement long a executer puisque traitement px par px)
  • * @access public
  • * @param int $factor paramètre de bruit (0-255)
  • * @return bool
  • */
  • public function addNoise($factor)
  • {
  • for($x=0;$x<$this->width;$x++)
  • {
  • for($y=0;$y<$this->height;$y++)
  • {
  • $rand = mt_rand(-$factor,$factor);
  • $rgb = imagecolorat($this->source,$x,$y);
  • $r = (($rgb>>16)& 0xFF)+$rand;
  • $g = (($rgb>>8)& 0xFF)+$rand;
  • $b = ($rgb & 0xFF)+$rand;
  • $color = imagecolorallocate($this->source,$r,$g,$b);
  • if(imagesetpixel($this->source,$x,$y,$color))
  • return true;
  • else
  • return false;
  • }
  • }
  • }
  • /**
  • * Netteté
  • * @access public
  • */
  • public function sharppen()
  • {
  • imagefilter($this->source,IMG_FILTER_MEAN_REMOVAL);
  • }
  • /**
  • * Modifie le contraste de l'image. Imagefilter remplace les calcul via matrice. 10x plus rapide
  • * @access public
  • * @param int $factor Facteur de flou
  • */
  • public function contrast($factor)
  • {
  • imagefilter($this->source,IMG_FILTER_CONTRAST,$factor);
  • }
  • /**
  • * Modifie la luminosité. Imagefilter remplace les calcul via matrice. 10x plus rapide
  • * @access private
  • * @param int $factor Facteur de flou
  • */
  • public function brightness($factor)
  • {
  • imagefilter($this->source,IMG_FILTER_BRIGHTNESS,$factor);
  • }
  • /**
  • * Créer une copie de l image original pour restauration ulterieur.
  • * @access public
  • */
  • public function duplicate()
  • {
  • $this->copie = imagecreatetruecolor($this->width,$this->height);
  • imagecopy($this->copie,$this->source,0,0,0,0,$this->width,$this->height);
  • }
  • /**
  • * Restaure la copie de sauvegarde de l'image
  • * @access public
  • */
  • public function restore()
  • {
  • $this->source = $this->copie;
  • }
  • /**
  • * Permet le changement de police. indiquer le chemin vers le fichier ttf
  • * @access public
  • * @param string $path Chemin vers la police
  • */
  • public function setFont($path)
  • {
  • $this->font = $path;
  • }
  • /**
  • * Permet de définir une couleur à utiliser
  • * @access public
  • * @param int $r composante rouge
  • * @param int $v composante verte
  • * @param int $b composante bleue
  • */
  • public function setColor($r,$v,$b)
  • {
  • $this->couleur = imagecolorallocate($this->source,$r,$v,$b);
  • }
  • /**
  • * Ecrit un texte sur l image aux positions données
  • * @access public
  • * @param string $texte Texte à afficher
  • * @param int $size Taille du texte
  • * @param int $x Position en X
  • * @param int $y Position en Y
  • * @param bool $rect Ajout ou non d'un rectangle blanc sous le texte
  • */
  • public function setText($texte,$size,$x,$y,$rect)
  • {
  • if($rect)
  • {
  • $rectText = imageftbbox($size,0,$this->font,$texte); // Retourne les coordoonées du text
  • $wText = abs($rectText[4]-$rectText[0]); // Largeur du texte
  • $hText = abs($rectText[1]-$rectText[5]); // hauteur du texte
  • $this->setColor(255,255,255); // Fond blanc
  • imagefilledrectangle($this->source,$x,($y-$hText),($x+$wText+5),($y+5),$this->couleur); //($y-$htext) permet de placer
  • // le rectangle au bon endroit
  • $this->setColor(0,0,0); // Texte noir
  • imagettftext($this->source,$size,0,$x,$y,$this->couleur,$this->font,$texte);
  • }
  • else
  • {
  • imagettftext($this->source,$size,0,$x,$y,$this->couleur,$this->font,$texte);
  • }
  • }
  • /**
  • * Redimensionne l'image. Si une des deux dimension = 0. Redimensionnement proportionnel sur celle donnée
  • * @param int $newW Largeur souahitée
  • * @param int $newH Hauteur souhaitée
  • * @access public
  • * @return bool
  • */
  • public function resize($newW,$newH)
  • {
  • if($newW == 0) // Largeur non spécifiée donc dimension basé sur hauteur
  • {
  • $scale = $newH/$this->height;
  • $newW = $this->width * $scale;
  • }
  • elseif($newH == 0) // Hauteur non spécifiée donc dimension basé sur largeur
  • {
  • $scale = $newW / $this->width;
  • $newH = $this->height * $scale;
  • }
  • $tempImg = imagecreatetruecolor($newW,$newH);
  • if(imagecopyresampled($tempImg,$this->source,0,0,0,0,$newW,$newH,$this->width,$this->height))
  • {
  • $this->source = $tempImg;
  • $this->width = $newW;
  • $this->height = $newH;
  • return true;
  • }
  • else
  • {
  • return false;
  • }
  • }
  • /**
  • * Crop une image aux dimensions voulues et à partir de l'endroit voulu
  • *
  • * @param int $cropW Largeur de la zone de crop
  • * @param int $cropH Hauteur de la zone de crop
  • * @param int $cropStartX Coordonnées en X de départ
  • * @param int $cropStartY Coordonnées en Y de départ
  • * @return bool
  • */
  • public function crop($cropW,$cropH,$cropStartX,$cropStartY)
  • {
  • $tempImg = imagecreatetruecolor($cropW,$cropH);
  • if(imagecopyresized($tempImg, $this->source, 0, 0, $cropStartX, $cropStartY, $cropW, $cropH, $cropW, $cropH))
  • {
  • $this->source = $tempImg;
  • $this->width = $cropW;
  • $this->height = $cropH;
  • return true;
  • }
  • else
  • {
  • return false;
  • }
  • }
  • /**
  • * Sauvegarde l'image sur le disque
  • * @access public
  • * @param string $file Nom et chemin de fichier
  • * @return bool
  • */
  • public function save($file,$qualite=95)
  • {
  • if($this->type==1)
  • {
  • if(imagegif($this->source,$file))
  • return true;
  • else
  • return false;
  • }
  • elseif($this->type == 2)
  • {
  • if(imagejpeg($this->source,$file,$qualite))
  • return true;
  • else
  • return false;
  • }
  • elseif($this->type == 3)
  • {
  • if(imagepng($this->source,$file))
  • return true;
  • else
  • return false;
  • }
  • }
  • /**
  • * Affiche l'image sur la sortie standard
  • * @access public
  • * @return img
  • */
  • public function display($qualite=100)
  • {
  • if($this->type==1)
  • {
  • header("Content-type: image/gif");
  • return imagegif($this->source);
  • }
  • elseif($this->type == 2)
  • {
  • header("Content-type: image/jpeg");
  • return imagejpeg($this->source,'',$qualite);
  • }
  • elseif($this->type == 3)
  • {
  • header("Content-type: image/png");
  • return imagepng($this->source);
  • }
  • }
  • /**
  • * Destructeur
  • */
  • public function __destruct()
  • {
  • imagedestroy($this->source);
  • @imagedestroy($tempImg);
  • if($this->copie!=null)
  • @imagedestroy($this->copie);
  • }
  • }
  • ?>
<?php
/**
 * Classe ImgTraitement
 *
 * Class De traitement d'image
 * <code>
 * $img = new Imgtraitement('nen.jpg');
 * $img->resize(320,0);
 * $img->save('test2.jpg');
 * </code>
 *
 * @version 1.1.0 
 * @author Olivier ROGER <>
 *       
 *
 */
 
 class ImgTraitement
 {
 	
 	/**
 	 * @access private
 	 * @var int
 	 */
 	private $width;
 	
 	/**
 	 * @var int
 	 * @access private
 	 */
 	 private $height;
 	 
 	 /**
 	 * Type de l image : 1 = gif ; 2 = jpeg; 3= png
 	 * @var string 
 	 * @access private
 	 * 
 	 */
 	 private $type;
 	 
 	 /**
	 * @var string $mime Type mime de l image
	 * @access private
	 */
	 private $mime;
 	 /**
 	 * @var img Fichier image source
 	 * @access private
 	 */
 	 private $source;
 	 
 	 private $copie;
	
	/**
	 * @var string Police d'ecriture selectionnee. Defaut verdanna.
	 * @access private
	 */
	 private $font;
	 
	 /**
	  * @var ressource Couleur choisi (par defaut bordeau)
	  * @access private
	  */
	 private $couleur;
	 
	 /**
	  * @var ressource autre image a coller sur l image d origine
	  * @access private
	  */
	 private $logo;
	 /**
	  * @var ressource Largeur du logo
	  * @access private
	  */
	 private $widthL;
	 /**
	  * @var ressource Hauteur du logo
	  * @access private
	  */
	 private $heightL;
	 /**
	  * @var ressource Type du logo
	  * @access private
	  */
	 private $typeL;
	 
	 /**
	  * @var array Info de l'image
	  * @access private
	  */
	 private $infoImage;
	 
	 /**
	  * @var int Poids de l'image
	  * @access private
	  */
	 private $poids;

 	/**
 	 * Construteur
 	 */
 	public function __construct($img)
 	{
 		if(!empty($img) && file_exists($img))
 		{
 			$info = getimagesize($img);
 			$this->width   = $info[0];
 			$this->height  = $info[1];
 			$this->type    = $info[2]; // 1:gif; 2:jpg; 3:png; 4:swf; 5:psd; 6:bmp; 7:tiff
 			$this->mime    = $info['mime'];
 			$this->copie   = null;
 			$this->source  = $this->createFromType($img);
 			if($this->source == false)
 			{
 				echo 'Format d\'image non supporté';
 				exit;
 			}
 			$this->couleur = imagecolorallocate($this->source,187,3,33);
 			$this->poids   = filesize($img);
 			$this->infoImage 			  = array();
 			$this->infoImage['extension'] = strchr($img, '.');
			$this->infoImage['extension'] = substr($this->infoImage['extension'], 1); // Récupère l'extension après le .
			$this->infoImage['extension'] = strtolower($this->infoImage['extension']);
 		}
 	}
 	
 	/**
 	 * Récupère les informations de l'image
 	 * @access public
 	 * @return array Information de l'image (reso,poids,extension,mime)
 	 */
 	public function getInfo()
 	{	
 		$this->infoImage['width']     = $this->width; 
 		$this->infoImage['height']    = $this->height;
		$this->infoImage['mime']      = $this->mime;
		$this->infoImage['poids']	  = round($this->poids/1024,2);
		
		return $this->infoImage;
 		
 	}
 	/**
 	 * Ajoute une image en tant que logo
 	 * @access public
 	 * @param string chemin vers l'image
 	 */
 	public function addLogo($logo)
 	{
 		list($this->widthL,$this->heightL,$this->typeL) = getimagesize($logo);
 		$this->logo = $this->createFromType($logo);
 		imagealphablending($this->logo,TRUE); // Activation de la transparence
 	}
 	
 	/**
 	 * Ajoute le logo à l'image principale
 	 * @access public
 	 * @param string $pos Position du logo : ct(centre),hg(haut gauche),hd,bg(bas gauche),bd(défaut)
 	 * @param int $opacite % d'opacité du logo , par défaut 75
 	 * @return bool 
 	 */
 	public function mergeLogo($pos='bd',$opacite=75)
 	{
 		if($pos =='hg')
 		{
 			$posX = 0;
 			$posY = 0;
 		}
 		elseif($pos=='hd')
 		{
 			$posX = ($this->width - $this->widthL);
 			$posY = 0;
 		}
 		elseif($pos == 'bg')
 		{
 			$posX = 0;
 			$posY = ($this->height - $this->heightL);
 		}
 		elseif($pos == 'bd')
 		{
 			$posX = ($this->width - $this->widthL);
 			$posY = ($this->height - $this->heightL);
 		}
 		elseif($pos == 'ct')
 		{
 			$posX = (($this->width/2) - ($this->widthL/2));
 			$posY = (($this->height/2) - ($this->heightL/2));
 		}

 		if(imagecopymerge($this->source,$this->logo,$posX,$posY,0,0,$this->widthL,$this->heightL,$opacite))
 			return true;
 		else
 			return false;
 	}
 	
 	/**
 	 * Créer une ressource image selon son type
 	 * @access protected
 	 * @param string image
 	 * @return ressource image
 	 */
 	protected function createFromType($img)
 	{
 		if($this->type==1)
 			$crea = imagecreatefromgif($img);
 		elseif($this->type == 2)
 			$crea = imagecreatefromjpeg($img);
 		elseif($this->type == 3)
 			$crea = imagecreatefrompng($img);
 		else
 			$crea = false;
 		
 		return $crea;
 	}

 	/**
 	 * Convertit l'image en niveau de gris. Imagefilter remplace les calcul via matrice. 10x plus rapide
 	 * @access public
 	 */
 	public function greyScale()
 	{
 		
 		imagefilter($this->source,IMG_FILTER_GRAYSCALE);
 	}
 	
 	/**
 	 * Ajoute du flou à l'image. Imagefilter remplace les calcul via matrice. 10x plus rapide
 	 * @access public
 	 * @param int $factor Facteur de flou
 	 */
 	public function blur($factor)
 	{
 		imagefilter($this->source,IMG_FILTER_GAUSSIAN_BLUR,$factor);
 	}
 	
	/**
	 * Ajoute du bruit à l'image. (relativement long a executer puisque traitement px par px)
	 * @access public
	 * @param int $factor paramètre de bruit (0-255)
	 * @return bool
	 */
	 public function addNoise($factor)
	 {
	 	
	 	for($x=0;$x<$this->width;$x++)
	 	{
	 		for($y=0;$y<$this->height;$y++)
	 		{
	 			$rand = mt_rand(-$factor,$factor);
	 			$rgb = imagecolorat($this->source,$x,$y);
	 			$r   = (($rgb>>16)& 0xFF)+$rand;
	 			$g   = (($rgb>>8)& 0xFF)+$rand;
	 			$b   = ($rgb & 0xFF)+$rand;
	 			
	 			$color = imagecolorallocate($this->source,$r,$g,$b);
	 			if(imagesetpixel($this->source,$x,$y,$color))
	 				return true;
	 			else
	 				return false;
	 		}
	 	}
	 }
	 
	 /**
	  * Netteté
	  * @access public
	  */
	 public function sharppen()
	 {
	 	imagefilter($this->source,IMG_FILTER_MEAN_REMOVAL);
	 }
	/**
	 * Modifie le contraste de l'image. Imagefilter remplace les calcul via matrice. 10x plus rapide
	 * @access public
	 * @param int $factor Facteur de flou
	 */
	 public function contrast($factor)
	 {
	  	imagefilter($this->source,IMG_FILTER_CONTRAST,$factor);
	 }
 	  
 	 /**
	 * Modifie la luminosité. Imagefilter remplace les calcul via matrice. 10x plus rapide
	 * @access private
	 * @param int $factor Facteur de flou
	 */
	 public function brightness($factor)
	 {
	  	imagefilter($this->source,IMG_FILTER_BRIGHTNESS,$factor);
	 }
	 
	 /**
	  * Créer une copie de l image original pour restauration ulterieur.
	  * @access public
	  */
	 public function duplicate()
	 {
	 	$this->copie = imagecreatetruecolor($this->width,$this->height);
	 	imagecopy($this->copie,$this->source,0,0,0,0,$this->width,$this->height);
	 }
	 
	 /**
	  * Restaure la copie de sauvegarde de l'image
	  * @access public
	  */
	  public function restore()
	  {
	  	$this->source = $this->copie;
	  }
	 
	 /**
	  * Permet le changement de police. indiquer le chemin vers le fichier ttf
	  * @access public
	  * @param string $path Chemin vers la police
	  */
	  public function setFont($path)
	  {
	  	$this->font = $path;
	  }
	  
	  /**
	   * Permet de définir une couleur à utiliser
	   * @access public
	   * @param int $r composante rouge
	   * @param int $v composante verte
	   * @param int $b composante bleue
	   */
	   public function setColor($r,$v,$b)
	   {
	   		$this->couleur = imagecolorallocate($this->source,$r,$v,$b);
	   }
	   
	   /**
	    * Ecrit un texte sur l image aux positions données
	    * @access public
	    * @param string $texte Texte à afficher
	    * @param int $size Taille du texte
	    * @param int $x Position en X
	    * @param int $y Position en Y
	    * @param bool $rect Ajout ou non d'un rectangle blanc sous le texte
	    */
	    public function setText($texte,$size,$x,$y,$rect)
	    {
	    	if($rect)
	    	{
	    		$rectText = imageftbbox($size,0,$this->font,$texte); // Retourne les coordoonées du text
	    		$wText    = abs($rectText[4]-$rectText[0]); // Largeur du texte
	    		$hText    = abs($rectText[1]-$rectText[5]); // hauteur du texte
	    		$this->setColor(255,255,255); // Fond blanc
	    		imagefilledrectangle($this->source,$x,($y-$hText),($x+$wText+5),($y+5),$this->couleur); //($y-$htext) permet de placer
	    																								// le rectangle au bon endroit
	    		$this->setColor(0,0,0); // Texte noir
	    		imagettftext($this->source,$size,0,$x,$y,$this->couleur,$this->font,$texte);
	    	}
	    	else
	    	{
	    		imagettftext($this->source,$size,0,$x,$y,$this->couleur,$this->font,$texte);
	    	}
	    }
	    
	   /**
	   * Redimensionne l'image. Si une des deux dimension = 0. Redimensionnement proportionnel sur celle donnée
	   * @param int $newW Largeur souahitée
	   * @param int $newH Hauteur souhaitée
	   * @access public
	   * @return bool
	   */
	 public function resize($newW,$newH)
	   {
	   		if($newW == 0) // Largeur non spécifiée donc dimension basé sur hauteur
	   		{
	   			$scale = $newH/$this->height;
	   			$newW  = $this->width * $scale;
	   		}
	   		elseif($newH == 0) // Hauteur non spécifiée donc dimension basé sur largeur
	   		{
	   			$scale = $newW / $this->width;
	   			$newH  = $this->height * $scale;
	   		}
	   		$tempImg = imagecreatetruecolor($newW,$newH);
	   		if(imagecopyresampled($tempImg,$this->source,0,0,0,0,$newW,$newH,$this->width,$this->height))
	   		{
	   			$this->source = $tempImg;
	   			$this->width  = $newW;
	   			$this->height = $newH;
	   			return true;
	   		}
	   		else
	   		{
	   			return false;
	   		}

	   }
		/**
		 * Crop une image aux dimensions voulues et à partir de l'endroit voulu
		 *
		 * @param int $cropW Largeur de la zone de crop
		 * @param int $cropH Hauteur de la zone de crop
		 * @param int $cropStartX Coordonnées en X de départ
		 * @param int $cropStartY Coordonnées en Y de départ
		 * @return bool
		 */
		public function crop($cropW,$cropH,$cropStartX,$cropStartY)
		{
			$tempImg = imagecreatetruecolor($cropW,$cropH);
			if(imagecopyresized($tempImg, $this->source, 0, 0, $cropStartX, $cropStartY, $cropW, $cropH, $cropW, $cropH))
			{
				$this->source = $tempImg;
				$this->width  = $cropW;
	   			$this->height = $cropH;
	   			return true;
			}
			else
			{
				return false;
			}
		}
  	  /**
	  * Sauvegarde l'image sur le disque
	  * @access public
	  * @param string $file Nom et chemin de fichier
	  * @return bool
	  */
	 public function save($file,$qualite=95)
	 {
	 	if($this->type==1)
	 	{
 			if(imagegif($this->source,$file))
 				return true;
 			else
 				return false;
	 	}
 		elseif($this->type == 2)
 		{
 			if(imagejpeg($this->source,$file,$qualite))
 				return true;
 			else
 				return false;
 		}
 		elseif($this->type == 3)
 		{
 			if(imagepng($this->source,$file))
 				return true;
 			else
 				return false;
 		}
	 }
	 
	 /**
	  * Affiche l'image sur la sortie standard
	  * @access public
	  * @return img
	  */
	 public function display($qualite=100)
	 {
	 	if($this->type==1)
	 	{
 			header("Content-type: image/gif");
 			return imagegif($this->source);
	 	}
 		elseif($this->type == 2)
 		{
 			header("Content-type: image/jpeg");
 			return imagejpeg($this->source,'',$qualite);
 		}
 		elseif($this->type == 3)
 		{
 			header("Content-type: image/png");
 			return imagepng($this->source);
 		}
	 }
	 
 	/**
 	 * Destructeur
 	 */
 	public function __destruct()
 	{
 		imagedestroy($this->source);
 		@imagedestroy($tempImg);
 		if($this->copie!=null)
 			@imagedestroy($this->copie);
 	}
 }
?>

Conclusion

Toutes les remarques sont les bienvenues , n'hésitez donc pas à donner voter avis :P
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de neigedhiver le 09/04/2008 20:04:11

    Salut,

    J'ai pas regardé en détails, mais après un rapide coup d'oeil, y'a deux choses qui ont retenu mon attention :
    - j'apprécie la documentation au format phpDoc (ou Doxygen, ou autre, bref), mais je déplore juste l'absence de commentaires non parsés dans le reste du code (en même temps, si ça se trouve, c'est pas justifié parce que suffisament simple et lisible). Corrolaire : j'apprécie la clarté du code. Au moins, on sait où on en est dans ce qu'on lit.
    - pour les comparaisons du genre : if($this->type==1) tu devrais utiliser des constantes, c'est plus facile à lire que des commentaires qui indiquent à quoi correspondent les valeurs 1, 2 etc

    const IMG_GIF = 1;
    const IMG_JPG = 2;
    const IMG_PNG = 3;

    if($this->type == self::IMG_GIF)

    Je trouve ça plus lisible...

    Bon encore un autre truc (parce que j'ai survolé une deuxième fois) : tu mets des commentaires avec // en fin de ligne... Syntaxiquement, c'est tout à fait valable. Personnellement (et là, ça n'engage que moi, c'est une question de goût), je préfère mettre des commentaires sur une ligne rien que pour eux, avant la ligne qu'ils commentent. Je trouve que c'est encore plus lisible. Par exemple :

    $rectText = imageftbbox($size,0,$this->font,$texte); // Retourne les coordoonées du text
    $wText = abs($rectText[4]-$rectText[0]); // Largeur du texte
    $hText = abs($rectText[1]-$rectText[5]); // hauteur du texte

    =>

    //Retourne les coordoonées du texte
    $rectText = imageftbbox($size,0,$this->font,$texte);
    // Largeur du texte
    $wText = abs($rectText[4]-$rectText[0]);
    // hauteur du texte
    $hText = abs($rectText[1]-$rectText[5]);

    C'est vraiment une question de convention, hein. Je sais que pour certains, ce sont des détails à la con, mais quand on veut un code clair, autant qu'il le soit le plus possible.

    Maintenant, une toute dernière chose, peut-être une piste pour améliorer la source (qui ne me semble pas mauvaise, même si elle ne me parait pas non plus révolutionnaire) : l'abstraction du traitement.
    Certaines portions de ton code sont récurrentes : pour un gif, jpeg ou png. Juste parce que certaines fonctions sont spécifiques au format.
    Tu gagnerais peut-être à avoir une classe abstraite pour la gestion de l'image, et des classes concrètes, une pour chaque format. Avec une factory qui instancie le bon objet selon le type d'image.
    Tu économises du code et tu peux ensuite rajouter autant de formats que tu le souhaites, sans changer une seule ligne de ta classe principale.

    Euh voilà pour un premier coup d'oeil...

  • signaler à un administrateur
    Commentaire de codefalse le 10/04/2008 09:40:47 administrateur CS 8/10

    Yop :)
    Je suis d'accord avec Neige sur ce qu'il dit, sauf la partie des commentaires, ou c'est subjectif :p Après comme il dit, c'est vraiment comme on veux, et ca ne change rien à la qualité du code :)

    Juste pour donner un contre exemple :

    const IMG_GIF = 1; // Type Gif
    const IMG_JPG = 2; // Type Jpg
    const IMG_PNG = 3; // Type Png

    Bon, dans ce cas ca sert à rien, mais c'est juste pour indiquer que le retour à la ligne dépends de la longueur du code (à mon avis, donc subjectif :p) :)

    Quant à ton code, rien à redire, il est propre, reste plus qu'à réduire la répétition de code tel que l'a souligné Neige, et tout sera bon ! :)

    Bon courage ! :)

  • signaler à un administrateur
    Commentaire de grunkz le 10/04/2008 10:10:43

    Merci de vos commentaires.
    Pour les constantes c'est pris en compte. En revanche au niveau de la factory, j'ai comme un doute sur le bénéfice dans ce cas là.
    Mes connaissances en design pattern étant plus que limitée je vais peut être dire une annerie mais :

    j'aurais besoin d'une factory qui créera un objet d'une de mes classe (par exemple new traitementImgJPG, ou traitementImgGIF) qui elle même dériveront de la classe ci dessus (les méthodes spécifique au format en moins).

    Donc au final ça va faire bcp de code pour éviter 3 if/else nan ?

    Après sémentiquement c'es tcertainement plus "propre" je vous l'accorde

  • signaler à un administrateur
    Commentaire de spipod le 10/04/2008 11:33:16 10/10

    Salut,

    Très bon travail.

    Mais une petite question : pourquoi dans ton code (exemple fonction save) utilises-tu des if / else plutôt qu'un switch ?

    N'est-ce pas plus lisible ?

    Genre :

    public function save($file,$qualite=95)
    {
        $ret=false;
        switch($this->type)
        {
            case IMG_GIF :
           if (imagegif($this->source,$file))
    $ret = true;
                break;
            case IMG_JPG :
                if( imagejpeg($this->source,$file,$qualite))
    $ret = true;
                break;
            case IMG_PNG :
           if (imagepng($this->source,$file))
    $ret = true;
                break;
        }
        return $ret;
    }

  • signaler à un administrateur
    Commentaire de grunkz le 10/04/2008 11:48:23

    C'est juste une préférence perso. Tant que le nombre de possibilités n'est pas élevé je préfère le if/else plutôt que le switch case.
    Après sur un grd nombre de possibilité je me force à utiliser le switch case qui sera plus rapide

  • signaler à un administrateur
    Commentaire de codefalse le 10/04/2008 11:55:31 administrateur CS

    En effet, le switch à été testé et prouvé comme étant plus rapide donc apportant un gain de performance. Pour des cas tels qu'énnoncés comme ici, c'est vrai qu'il serait bien approprié. En fait il faut l'utiliser  dans ces circonstances là, et utiliser if dans les autres circonstances. C'est pas une histoire de quantité.

    Apres ca marche très bien donc pas de soucis :p

    Pour la factory, je pense que Neige voulait plutot dire que tu fait une classe ImgFactory avec comme constructeur le type (entre autre) et quand tu fait un
    new ImgFactory ('png');

    Celui ci va instancier ImgPng (par exemple) et passer en parametre à ta classe :
    __construct ($sType) {
       switch ($sType) {
          case 'png':
             $oImgType = new ImgPng ();
             break;
          case 'jpg':
             $oImgType = new ImgJpg ();
             break;
          //etc...
       }
       return new ImgTraitement ($oImgType);
    }

    Du coup dans ta classe ImgTraitement tu n'aura plus à faire :
    return imagejpeg($this->source,'',$qualite); (par exemple)

    mais
    return $this->_oImgType->createImage ($this->source,'',$qualite);

    et c'est ton instance de $_oImgType, instance de ImgPng ou ImgJpg, ou etc, qui fera le imagejpeg ou imagepng en fonction du type demandé.

    Je sais pas si j'ai été assez clair ?
    et Neige, dit moi si c'est bien à cela que tu pensais :p

  • signaler à un administrateur
    Commentaire de neigedhiver le 10/04/2008 14:40:04

    Salut,

    Concernant le if/else et le switch, il me semble me souvenir que le case demande plus de ressources à la "création", mais est plus rapide pour les tests suivants. Donc, toujours d'après mes souvenirs (et ceux-ci sont peut-être erronés), il me semble que le if/else est plus intéressant pour un petit nombre de cas, et le case pour un plus grand nombre. Il me semble (toujours ces souvenirs, merci Alzheimer...) que c'est ce qu'avaient donnés mes tests persos.

    Concernant la Factory, l'idée est d'appeler une méthode statique qui va procéder à un minimum d'opérations sur l'image et va :
    - déterminer le type d'après son extension
    - instancier un objet ImgTraitement approprié (ImgPNG, ImgJPG, ...)
    - retourner cet objet

    Ensuite, la question des if/else et des case ne se posera plus, puisque le test aura été fait au départ.
    On ne gagne pas, ainsi, que quelques lignes de code. On y gagne vraiment beaucoup en modularité.
    Comme je le disais, on peut ensuite rajouter des objets pour n'importe quel type d'image (gd, jpg, png, gif, xpn, etc). L'idée est que si la classe est assez bien foutue (plus précisément la méthode statique d'instanciation) on n'a par la suite aucune ligne de code à rajouter dans cette classe pour qu'un nouveau type soit pris en charge : il suffit d'écrire le code du "module" propre à ce type.
    Plus loin : au lieu de se limiter à GD, qui finalement ne gère pas tous les formats, les classes concrètes pourraient utiliser soit GF, ImageMagick, voire une autre librairie. Cela, de manière tout à fait transparente, et toujours sans toujours une ligne de code dans la classe principale.
    On n'y gagne pas que quelques lignes de code avec des if/else : on y gagne des heures de travail pour plus tard.
    Du coup, il faut une interface qui définisse quelles méthodes les classes spécialisées doivent implémenter.
    Finalement, c'est rigoureusement le même principe que les classes d'abstraction de base de données : on peut ajouter une classe pour n'importe quel SGBDR sans toucher une ligne de code de ce qui a déjà été fait.

  • signaler à un administrateur
    Commentaire de codefalse le 10/04/2008 15:12:50 administrateur CS

    C'est tout bonnement le principe de la Poo :)

    Alzheimer, vraiment Neige ? à 30 ans ? !!! ;)

  • signaler à un administrateur
    Commentaire de neigedhiver le 10/04/2008 15:20:33

    Si tu savais... Je m'inquiète déjà, alors imagine dans 30 autres années... Mon dieu...

  • signaler à un administrateur
    Commentaire de Eregon le 13/04/2008 19:56:44

    J'ai commencé une classe de création d'image à partir de GD (40 de méthodes et 500lignes),
    et donc je ne peux qu'approuver l'idée.

    Sauf que l'on voit assez vite le défaut de GD quand on travaille sur l'épaisseur...
    Impossible de modifier celle des ellipses, incohérences graves lors d'une épaisseur supérieure à 2 à proximité des angles 45°+k90°
    Pour faire simple:
    http://eregon.franceserv.com/tmp/q1gd.php.png

    J'ai donc complètement changé d'optique pour passer en SVG. Plus besoin d'extension...
    La classe est beaucoup plus orientée objet(car SVG, c'est du xml...).
    Qualité infinie, calcul chez l'utilisateur donc pas d'explosion de mémoire...
    http://eregon.franceserv.com/tmp/test.png

    Je rentre un peu trop dans un débat, donc revenons à ta classe:
    -Le code est assez clair, et les fonctions explicites
    -Les fonctions sont de 2 types: il y a de la gestion globale d'image(recadrage, constraste) et puis interne(texte).
    =>J'avais plus approfondi le texte car on peut voir que ttfbox ne renvoie pas souvent le même valeur pour l'ordonnée du point haut gauche et haut droite. De même avec la rotation, il faut modifier différemment l'ordonnée.

    ...
    Je sens que je vais poster ma classe ... Trop de choses à dire ...
    ...

    Pour les commentaires, je déteste ce genre à la /* * */, surtout avec les @access public, alors qu'il suffit de savoir lire qqs lignes plus bas. Il est parfois utile de préciser le type, mais je trouve plus simple de mettre des noms explicites et de mettre ça en une ligne en dessous de la première ligne de fonction:
    public function fill_arc(Point $p, $w, $h, $start, $end, $color, $style)
    {//filled arc(Point $origin, int $width, int $height, float $start_angle, float $end_angle, color $color, IMG_ARC_ CONSTANT(PIE,CHORD,NOFILL,EDGED) $style)

    Pour les types d'images, en 1 switch:
    switch(strtolower(substr($name, -3, 3)))
    {
    case 'jpg':
    case 'peg':
    ImageJpeg($this->img, $name, 100*$quality);
    break;
    case 'gif':
    ImageGif($this->img, $name);
    break;
    case 'png':
    ImagePng($this->img, $name, 9*(1-$quality));
    break;
    }

    Quand aux idées de factory, p-e si les librairies sont proches, mais entre SVG et GD, ce n'est pas vraiment possible, le style est défini de manière bien différente.

    Bon dès que j'ai le temps de commenter un peu, je poste ma classe ;)

  • signaler à un administrateur
    Commentaire de neigedhiver le 13/04/2008 20:13:16

    Salut,

    @Eregon : "Pour les commentaires, je déteste ce genre à la /* * */, surtout avec les @access public, alors qu'il suffit de savoir lire qqs lignes plus bas."

    C'est pas un caprice de l'auteur, c'est le respect de phpDOc qui permet de générer la documentation d'une classe ou d'un package automatiquement grâce à une appli spécialisée.
    Le résultat se voit sur phpdoc.org, c'est aussi le même genre avec doxygen qui a généré la doc de la SPL.

    Alors si tu détestes les codes documentés qui permettent de s'y retrouver et de générer la doc soi-même à partir du code source, ben... moi j'apprécie... Et je pense, très sincèrement, ne pas être le seul...

  • signaler à un administrateur
    Commentaire de Eregon le 14/04/2008 20:23:30

    J'ai dit  que je préférais une autre notation, donc j'apprécie les codes commentés, et je ne lis pas ceux qui le sont trop peu.

    Je sais que c'est une convention, mais je ne vois pas l'intérêt des @access et certaines autres propriétés.

    Si certains pensent que ça facilite de faire les commentaires avec une appli, je ne pense pas que les descriptions et types(en php) puissent être générés automatiquement... Donc les seules propriétés intéressantes sont celles qu'on entre soi-même.(C'est mon avis)
    Alors autant le faire soi même...

  • signaler à un administrateur
    Commentaire de neigedhiver le 14/04/2008 20:27:14

    Je crois que t'as pas compris...
    C'est pas l'appli qui fait les commentaires, mais les commentaires qui servent à générer la doc via une appli.
    En l'occurrence,

    @access private

    permet d'indiquer dans la doc que la méthode ou la propriété a une visibilité privée. Générer des commentaires avec une appli, voilà bien une drôle d'idée... Renseigne toi sur phpDoc, visiblement, tu ne sais pas à quoi ça sert...

  • signaler à un administrateur
    Commentaire de Eregon le 14/04/2008 21:36:43

    Ok, je n'ai rien dit pour l'appli.

    Néanmoins je trouve ce genre de commentaires /* * * */ encombrants et ça double souvent le nombre de lignes.

    Quand à phpDoc, j'ai l'impression que sa réputation est surtout basée sur son utilité en Java(d'après ce que j'ai lu phpDoc en dérive). Car je pense que le module pourrait lui même remarquer les "private,public,protected" devant les fonctions.

    Mais je dévie du sujet, et comme je me heurte probablement à tous les utilisateurs de phpDoc, je ne vais pas continuer. Néanmoins, pour moi, la meilleure documentation est faite main en commentaires dans le code ou si plus complexe dans des fichiers à part.
    Quand à l'utilité de détecter le hiérarchie des classes, perso je l'indique toujours en début de script.

    Donc je comprends l'attrait de phpDoc, mais la notation dans un code me semble exagérée pour certaines propriétés.

  • signaler à un administrateur
    Commentaire de brunoperel le 14/04/2008 23:13:54

    Salut,

    Au risque de passer pour un newbie complet : saurais-tu pourquoi j'obtiens l'erreur :
    Fatal error: Call to undefined function imagefilter() in /demo/traitementImage.class.php on line 232
    ?
    Parce que mon GD 2 est activé et tout...
    J'ai envie de dire "bonne source" mais c'est encore prématuré je crois :-D

  • signaler à un administrateur
    Commentaire de neigedhiver le 15/04/2008 01:02:15

    Salut,

    Moi j'aurais tendance à dire que tu n'es pas en PHP 5... http://fr.php.net/imagefilter
    Ou alors, GD n'est pas installé comme il faut.

  • signaler à un administrateur
    Commentaire de brunoperel le 15/04/2008 11:21:22

    Si pourtant je suis bien en PHP5 :
    http://mpteu.kelio.org/info.php
    Bon, j'essaierai avec un autre serveur...

  • signaler à un administrateur
    Commentaire de etaty le 16/04/2008 13:01:27

    Fatal error: Call to undefined function imagefilter() in /demo/traitementImage.class.php on line 232
    je confirme pour cette erreur avec l'image d'exemple !

  • signaler à un administrateur
    Commentaire de grunkz le 17/04/2008 09:51:39

    Doc php : Note: Cette fonction n'est disponible que si PHP(5) est compilé avec la version embarquée de la bibliothèque GD.
    Donc vos problèmes viennent surement de là

  • signaler à un administrateur
    Commentaire de brunoperel le 17/04/2008 15:21:35

    qu'est-ce que ça veut dire "version embarquée" ? :-$
    Si il faut avoir accès au serveur en tant qu'admin, c'est fichu pour moi :'-(

  • signaler à un administrateur
    Commentaire de neigedhiver le 17/04/2008 15:32:20

    Salut,

    http://fr.php.net/manual/fr/image.setup.php

    Note:  Depuis PHP 4.3, il existe une version de GD  qui est distribuée avec PHP. Cette version contient des fonctionnalités supplémentaires, comme les canaux alpha, et il est recommandé de l'utiliser de préférence à la bibliothèque externe, car elle est mieux supportée, et bien plus stable.

    embarquée != externe

  • signaler à un administrateur
    Commentaire de lonva6 le 23/04/2008 12:07:22

    Elle est bien sympa cette class quand meme et super utile
    jvais essayer de l'optimiser un peu.. et aussi rajouter des fonctions
    genre :
      - Au lien de $r,$v,$b mettre une couleur en hexa type #8FEC34 ou 8FEC34 ou 255:0:150
      - Des autres effets comme Negatif ou bien Colorisation ou encore Sepia
      - Une gestion des erreurs.. etc..

    bref j'essaye de faire ca dès que j'ai un peu de temp..

Ajouter un commentaire

Pub



Appels d'offres

Animation Flash alimen...
Budget : 6 000€
Creation portail video
Budget : 3 000€
Site de e-commerce
Budget : 5 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Téléchargements

Boutique

Boutique de goodies CodeS-SourceS