begin process at 2012 05 27 19:26:23
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Class et Objet ( POO )

 > MY.PICS : TRAITEMENT D'IMAGES NON DESTRUCTIF

MY.PICS : TRAITEMENT D'IMAGES NON DESTRUCTIF


 Information sur la source

Note :
8 / 10 - par 1 personne
8,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Class et Objet ( POO ) Classé sous :miniatures, gd, images, thumb, inwebo Niveau :Initié Date de création :11/11/2009 Date de mise à jour :17/06/2011 00:23:08 Vu / téléchargé :2 684 / 128

Auteur : inwebo

Ecrire un message privé
Site perso
Commentaire sur cette source (14)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Nécessite PHP5 et GD2

Création et manipulation d'images grâce à la librairie GD2 et PHP5, attention pensez à activer GD2 !
Permet la manipulation d'image (rogner, filtres etc) et leur sauvegarde sans altérer le fichier source.

Cette class permet :
- Créer une nouvelle image.
- Ouvrir une image (sans spécifier le type)
- Conversion d'image
- De fusionner des images (pour ajouter un watermark a vos images par ex)
- De redimensionner des images (selon la hauteur, largeur, taille fixe)
- De rogner une image
- D'afficher une image dans le navigateur
- D'ajouter des filtres sur une image (à la photoshop)
- Ajouter un masque d'opacité (canal alpha) sur vos images (pour mettre des angles arrondis par exemples)
- Ajouter un motif à une image
- De sauvegarder les traitements sans altérer l'image d'origine
        - De manipuler les fichiers BMP


Source

  • <?php
  • /**
  • * Fichier à inclure inc.class.pics.php5
  • *
  • * LICENSE: Paternité Pas d'Utilisation Commerciale
  • *
  • * @category inc
  • * @package inc.class
  • * @subpackage inc.class.pics
  • * @copyright 2011 Inwebo
  • * @license http://creativecommons.org/licenses/by-nc-nd/2.0/fr/
  • * @version Mai 2011
  • * @link http://www.inwebo.net/
  • * @since Novembre 2009
  • */
  • /**
  • * Création et manipulation d'images
  • *
  • * Création et manipulation d'images grâce à la librairie GD2 et PHP5, attention pensez à activer GD2 !
  • * Permet la manipulation d'image (rogner, filtres etc) et leur sauvegarde sans altérer le fichier source.
  • *
  • *
  • * MIXED __construct() : 1 si instanciation réussie sinon lance exception
  • * MIXED newPics() : Ressource si création de l'image réussie sinon lance exception
  • * MIXED open() : Ressource si l'image est ouverte correctement sinon lance exception
  • * STRING name : Retourne le nom d'un fichier sans son extension
  • * ARRAY info : Retourne la largeur et la hauteur d'une image
  • * MIXED merge() : 0 si les images n'existent pas, sinon renvoi la resource image de deux images fusionnées
  • * MIXED resize() : 0 si les images n'existent pas, sinon renvoi la resource image redimensionnée
  • * MIXED crop() : 0 si les images n'existent pas, sinon renvoi la resource image de deux images rognée
  • * RESOURCE filter() : RESOURCE image avec un filtre appliqué
  • * RESOURCE mask() : RESOURCE image avec un masque d'opacité appliqué sinon 0
  • * RESOURCE pattern() : 1 si motif appliqué sur une image sinon exception
  • * RESOURCE display() : Affiche une ressource image dans le navigateur
  • * RESOURCE imagecreatefrombmp() : Création d'une ressource GD à partir d'une image au format BMP
  • * BOOL save() : 1 si la sauvegarde s"est correctement déroulée, sauvegarde la ressource courante sous forme d'un fichier image
  • * BOOL saveByActions() : Sauvegarde les traitements dans un fichier
  • * BOOL loadByActions() : Charge des traitements
  • * VOID reset : Vide la pile courante de traitement éffectués sur la ressource image
  • * STRING __tostring : Infos sur l'objet courant
  • */
  • /**
  • * Définition des flags nécessaires.
  • */
  • // Type
  • define ('PNG', 'PNG');
  • define ('JPEG', 'JPEG');
  • define ('GIF', 'GIF');
  • define ('JPG', 'JPEG');
  • define ('BMP', 'BMP');
  • // Palette
  • define ('TRUE_COLOR', 'TRUE_COLOR');
  • define ('INDEXED', 'INDEXED');
  • // New filter
  • define ('IMG_FILTER_SEPIA', 'IMG_FILTER_SEPIA');
  • // Position CROP
  • define ('TOP_LEFT','TOP_LEFT');
  • define ('TOP', 'TOP');
  • define ('TOP_RIGHT','TOP_RIGHT');
  • define ('RIGHT', 'RIGHT');
  • define ('BOTTOM_RIGHT', 'BOTTOM_RIGHT');
  • define ('BOTTOM', 'BOTTOM');
  • define ('BOTTOM_LEFT', 'BOTTOM_LEFT');
  • define ('LEFT', 'LEFT');
  • define ('CENTER', 'CENTER');
  • define ('CUSTOM', 'CUSTOM');
  • // Alpha
  • define ('RESIZE_TO_MASK_SIZE', 'RESIZE_TO_MASK_SIZE');
  • define ('RESIZE_TO_PICTURES_SIZE', 'RESIZE_TO_PICTURES_SIZE');
  • // Save
  • define ( 'NEW_FILE', 'NEW_FILE' );
  • define ( 'REPLACE_FILE', 'REPLACE_FILE' );
  • define ( 'STACK', 'STACK' );
  • // Type instance
  • define ( 'LOAD_FILE', 'LOAD_FILE');
  • define ( 'NEW_GD', 'NEW_GD');
  • class Pics {
  • // Ressource GD courante
  • public $_gdPics;
  • public $height;
  • public $width;
  • public $picsType;
  • public $src;
  • // Pile de traitement faits sur l'image courante
  • public $stack;
  • // getters
  • public function getHeight() {
  • return $this->height;
  • }
  • public function getWidth() {
  • return $this->width;
  • }
  • public function getPicsType() {
  • return $this->type;
  • }
  • public function getGdPics() {
  • return $this->_gdPics;
  • }
  • /**
  • * Instanciation de la class ouverture d'une image existante $nameOrLength
  • * Ou création d'une nouvelle ressource image de longueur $nameOrLength
  • * et de hauteur $height.
  • *
  • * @arguments $nameOrLength STRING Chemin d'accès d'une image
  • * INT Largeur d'une nouvelle image
  • *
  • * @arguments $height NULL Si $nameOrLength est une chaine
  • * INT Hauteur d'une nouvelle image
  • *
  • *
  • * @return TRUE Si la nouvelle ressource image est crée avec succès
  • *
  • * @throw EXCEPTION Si $nameOrLength n'est pas un chemin d'accès valide
  • * Ou si $nameOrLength et $height ne sont pas des entiers
  • */
  • public function __construct( $nameOrLength, $height = NULL ) {
  • $this->stack = array();
  • if ( !extension_loaded( 'gd' ) ) {
  • throw new Exception('GD2 disabled');
  • }
  • if( is_file( $nameOrLength ) && $height === NULL ) {
  • $this->_gdPics = $this->open( $nameOrLength ) ;
  • $this->src = $nameOrLength ;
  • $this->type = LOAD_FILE ;
  • $this->height = imagesy($this->_gdPics) ;
  • $this->width = imagesx($this->_gdPics) ;
  • }
  • elseif( is_int( $nameOrLength ) && is_int( $height ) ) {
  • // Demande une nouvelle ressource image
  • $this->_gdPics = $this->newPics( $nameOrLength, $height ) ;
  • $this->width = $nameOrLength ;
  • $this->height = $height ;
  • $this->type = NEW_GD ;
  • }
  • else {
  • throw new Exception('Missing ressource or pics doesn\'t exist');
  • }
  • $this->stack[] = array( __FUNCTION__, func_get_args() );
  • return TRUE;
  • }
  • /**
  • * Créer une nouvelle ressource image, de largeur $largeur, de hauteur $hauteur, avec comme nombre de couleur
  • * $flag, de couleur RGB $R, $G, $B, et comme opacité $alpha
  • *
  • *
  • * @arguments INT $largeur, largeur en pixel
  • * INT $hauteur, hauteur en pixel
  • * STRING $flag DEFAULT TRUE_COLOR image 32 bits
  • * INDEXED image 1 bits
  • * INT $alpha opacite 0 : opacite complete, 127 transparence complete
  • * @return RESOURCE images
  • */
  • public function newPics( $largeur, $hauteur, $flag = TRUE_COLOR, $R = '255', $G = '255', $B = '255', $alpha = '127' ) {
  • switch ($flag) {
  • case TRUE_COLOR :
  • $pictures = imagecreatetruecolor($largeur, $hauteur);
  • $fond = imagecolorallocatealpha($pictures, $R, $G, $B, $alpha);
  • imagefill($pictures, 0, 0, $fond);
  • imagesavealpha($pictures, true);
  • break;
  • case INDEXED :
  • $pictures = imagecreate($largeur, $hauteur);
  • $fond = imagecolorallocatea($pictures, $R, $G, $B);
  • imagefill($pictures, 0, 0, $fond);
  • break;
  • default :
  • throw new Exception ('Bad $flag, try : TRUE_COLOR, INDEXED');
  • break;
  • }
  • $this->stack[] = array(__FUNCTION__, func_get_args() );
  • return $pictures;
  • }
  • /**
  • * Creation d'une ressource image gd
  • *
  • * @arguments STRING $pictures chemin d'accés à une image
  • * @return BOOL 0 si une erreur est survenuee
  • * RESOURCE images
  • */
  • public function open( $pictures ) {
  • if( !is_file($pictures) ) { return FALSE; }
  • $pictures_param = $this->infos( $pictures );
  • switch( $pictures_param['mime'] ) {
  • case 'image/png' :
  • return imagecreatefrompng($pictures);
  • break;
  • case 'image/jpeg' :
  • return imagecreatefromjpeg($pictures);
  • break;
  • case 'image/gif' :
  • return imagecreatefromgif($pictures);
  • break;
  • case 'image/x-ms-bmp' :
  • case 'image/bmp' :
  • return $this->imagecreatefrombmp($pictures);
  • break;
  • default :
  • return FALSE;
  • break;
  • }
  • }
  • /**
  • * Retourne une ressource GD à partir d'une image BMP
  • *
  • * @arguments STRING $filename chemin d'accés à l'image BMP
  • * @author DHKold
  • * @url http://www.php.net/manual/en/function.imagecreate.php#53879
  • * @thanks !
  • */
  • private function imagecreatefrombmp($filename) {
  • // Ouverture du fichier en mode binaire
  • if (! $f1 = fopen($filename,"rb")){ return FALSE; }
  • //1 : Chargement des entêtes FICHIER
  • $FILE = unpack( "vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread( $f1, 14 ) );
  • if ($FILE['file_type'] != 19778){ return FALSE; }
  • //2 : Chargement des entêtes BMP
  • $BMP = unpack( 'Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
  • '/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
  • '/Vvert_resolution/Vcolors_used/Vcolors_important', fread( $f1, 40 ) );
  • $BMP['colors'] = pow( 2, $BMP['bits_per_pixel'] );
  • if ( $BMP['size_bitmap'] == 0 ) {
  • $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
  • }
  • $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel'] / 8;
  • $BMP['bytes_per_pixel2'] = ceil( $BMP['bytes_per_pixel'] );
  • $BMP['decal'] = ( $BMP['width'] * $BMP['bytes_per_pixel'] / 4 );
  • $BMP['decal'] -= floor( $BMP['width']*$BMP['bytes_per_pixel'] / 4 );
  • $BMP['decal'] = 4 - ( 4 * $BMP['decal'] );
  • if ( $BMP['decal'] == 4 ){
  • $BMP['decal'] = 0;
  • }
  • //3 : Chargement des couleurs de la palette
  • $PALETTE = array();
  • if ( $BMP['colors'] < 16777216 && $BMP['colors'] != 65536 ) {
  • $PALETTE = unpack('V' . $BMP['colors'], fread( $f1, $BMP['colors'] * 4 ) );
  • }
  • //4 : Création de l'image
  • $IMG = fread( $f1, $BMP['size_bitmap'] );
  • $VIDE = chr( 0 );
  • $res = imagecreatetruecolor( $BMP['width'], $BMP['height'] );
  • $P = 0;
  • $Y = $BMP['height'] - 1;
  • while ( $Y >= 0 ) {
  • $X = 0;
  • while ( $X < $BMP['width'] ) {
  • if ($BMP['bits_per_pixel'] == 24) {
  • $COLOR = unpack("V",substr($IMG,$P,3).$VIDE);
  • }
  • elseif ( $BMP['bits_per_pixel'] == 16 ) {
  • $COLOR = unpack( "n", substr( $IMG, $P, 2 ) );
  • $COLOR[1] = $PALETTE[ $COLOR[1] + 1 ];
  • }
  • elseif ( $BMP['bits_per_pixel'] == 8 ) {
  • $COLOR = unpack( "n", $VIDE . substr( $IMG, $P, 1 ) );
  • $COLOR[1] = $PALETTE[$COLOR[1]+1];
  • }
  • elseif ( $BMP['bits_per_pixel'] == 4 ) {
  • $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
  • if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F);
  • $COLOR[1] = $PALETTE[$COLOR[1]+1];
  • }
  • elseif ( $BMP['bits_per_pixel'] == 1 ) {
  • $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
  • if(($P*8)%8 == 0) $COLOR[1] = $COLOR[1] >>7;
  • elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6;
  • elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5;
  • elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4;
  • elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3;
  • elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2;
  • elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1;
  • elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1);
  • $COLOR[1] = $PALETTE[$COLOR[1]+1];
  • }
  • elseif ($BMP['bits_per_pixel'] == 16) {
  • $COLOR = unpack("v",substr($IMG,$P,2));
  • $blue = (($COLOR[1] & 0x001f) << 3) + 7;
  • $green = (($COLOR[1] & 0x03e0) >> 2) + 7;
  • $red = (($COLOR[1] & 0xfc00) >> 7) + 7;
  • $COLOR[1] = $red * 65536 + $green * 256 + $blue;
  • }
  • else { return FALSE; }
  • imagesetpixel($res,$X,$Y,$COLOR[1]);
  • $X++;
  • $P += $BMP['bytes_per_pixel'];
  • }
  • $Y--;
  • $P+=$BMP['decal'];
  • }
  • //Fermeture du fichier
  • fclose($f1);
  • return $res;
  • }
  • /**
  • * Retourne un nom de fichier $fichier sans son extension, utile pour PHP < 5.2.0
  • *
  • * @arguments STRING $fichier nom de fichier avec son extension
  • * @return STRING nom de fichier sans son extension
  • */
  • protected function name( $fichier ) {
  • return basename ( $fichier, strrchr( $fichier, '.' ) );
  • }
  • /**
  • * Renvoie les propriétés d'une image $pictures voir function getimagesize()
  • * dans le manuel PHP
  • *
  • * @arguments STRING $pictures chemin d'accès à une image ou une ressource
  • * @return BOOL FALSE si une erreur est survenuee
  • * TRUE en cas de succès
  • */
  • protected function infos( $pictures ) {
  • if( !is_resource($pictures) ) {
  • return getimagesize( $pictures ) ;
  • }
  • else {
  • $values["Width"] = imagesx( $pictures );
  • $values["Height"] = imagesy( $pictures );
  • return $values;
  • }
  • }
  • /**
  • * Copie une image $picturestomerge avec comme opacité $picturestomergeopacity dans la ressource GD
  • * courante dans une zone prédéfinie $flag avec une marge $margin , ou à l'endroit souhaité avec
  • * comme coordonnées ($x_origin, $y_origin).
  • *
  • * @arguments STRING $picturestomerge l'image à inserer dans $pictures
  • * INT $picturestomergeopacity 0 : opaque, 127 transparent
  • * CONST $flag voir set_crop_pics()
  • * INT $x_origin coordonnée x de l'image à coller
  • * INT $y_origin coordonnée y de l'image à coller
  • * INT $margin marge souhaitée en pixel
  • * @return BOOL 1 en cas de succès
  • *
  • */
  • public function merge( $picturestomerge, $flag = CENTER, $picturestomergeopacity = 99, $x_origin = NULL, $y_origin = NULL, $margin = NULL ) {
  • // var_dump($picturestomerge);
  • if( is_object( $picturestomerge ) ) {
  • $pictures = $picturestomerge->_gdPics ;
  • $picsToMergeWidth = $picturestomerge->getWidth();
  • $picsToMergeHeight = $picturestomerge->getHeight();
  • }
  • elseif( is_string( $picturestomerge ) ) {
  • $temp = new Pics($picturestomerge);
  • $pictures = $temp->_gdPics;
  • $picsToMergeWidth = $temp->getWidth();
  • $picsToMergeHeight = $temp->getHeight();
  • }
  • elseif( is_resource( $picturestomerge ) ) {
  • $pictures = $picturestomerge;
  • $picsToMergeWidth = imagesx($picturestomerge);
  • $picsToMergeHeight = imagesy($picturestomerge);
  • }
  • static $x ;
  • static $y ;
  • switch ($flag) {
  • case TOP_LEFT:
  • $x = 0 + $margin;
  • $y = 0 + $margin ;
  • break;
  • case TOP:
  • $x = ($this->getWidth() - $picsToMergeWidth) / 2;
  • $y = 0 + $margin;
  • break;
  • case TOP_RIGHT:
  • $x = ($dest_im[0] - $src_im[0]) - $margin;
  • $y = 0 - $margin;
  • break;
  • case RIGHT:
  • $x = ($dest_im[0] - $src_im[0]) - $margin;
  • $y = ($dest_im[1] - $src_im[1]) / 2;
  • break;
  • case BOTTOM_RIGHT:
  • $x = ($dest_im[0] - $src_im[0]) - $margin;
  • $y = ($dest_im[1] - $src_im[1]) - $margin;
  • break;
  • case BOTTOM:
  • $x = ($dest_im[0] - $src_im[0]) / 2;
  • $y = ($dest_im[1] - $src_im[1]) - $margin;
  • break;
  • case BOTTOM_LEFT :
  • $x = 0 + $margin;
  • $y = ($dest_im[1] - $src_im[1]) - $margin;
  • break;
  • case LEFT :
  • $x = 0 + $margin;
  • $y = ($dest_im[1] - $src_im[1]) / 2;
  • break;
  • case CENTER :
  • $x = floor( ( $this->getWidth() - $picsToMergeWidth ) / 2);
  • $y = floor( ( $this->getHeight() - $picsToMergeHeight ) / 2);
  • break;
  • case CUSTOM :
  • $x = $x_origin;
  • $y = $y_origin;
  • break;
  • default :
  • throw new Exception ('Bad $flag, try : TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT, LEFT, CENTER, CUSTOM');
  • break;
  • }
  • imagecopymerge( $this->_gdPics, $temp->_gdPics, $x, $y, 0, 0, $picsToMergeWidth, $picsToMergeHeight , $picturestomergeopacity );
  • $this->stack[] = array(__FUNCTION__, func_get_args() );
  • unset($temp);
  • return true;
  • }
  • /**
  • * Redimensionne l'image courante, avec proportionalité sur la hauteur $new_width, largeur $new_height
  • * ou selon une taille prédéfinie ($new_width, $new_height)
  • *
  • * @arguments INT $new_width taille en pixel de la largeur voulue
  • * INT $new_height taille en pixel de la hauteur voulue
  • *
  • * @return BOOL 0 si une erreur est survenue
  • * RESOURCE images
  • */
  • public function resize( $new_width = NULL, $new_height = NULL ) {
  • if( $this->type == LOAD_FILE ) {
  • $pics_param = self::infos( $this->src ) ;
  • $pictures_origin = self::open( $this->src ) ;
  • // $pictures_origin = $this->_gdPics ;
  • }
  • else {
  • $pics_param[0] = $this->width ;
  • $pics_param[1] = $this->height ;
  • }
  • // Resize fixed width and height
  • if( isset( $new_width ) && isset( $new_height ) ) {
  • $width = $new_width;
  • $height = $new_height;
  • }
  • // Resize by new width
  • elseif( isset( $new_width ) && is_null( $new_height ) ) {
  • // Ratio by width
  • if( $new_width > $pics_param[0] ) {
  • $ratio = $new_width / $pics_param[0] ;
  • $width = $new_width ;
  • $height = round( $pics_param[1] * $ratio ) ;
  • }
  • else {
  • $ratio = $pics_param[0] / $new_width ;
  • $width = $new_width ;
  • $height = round( $pics_param[1] / $ratio ) ;
  • }
  • }
  • // Resize by new height
  • elseif( isset( $new_height ) && is_null( $new_width ) ) {
  • // Ratio by height
  • if( $new_height > $pics_param[1] ) {
  • $ratio = $new_height / $pics_param[1] ;
  • $width = round( $pics_param[0] * $ratio ) ;
  • $height = $new_height ;
  • }
  • else {
  • $ratio = $pics_param[1] / $new_height ;
  • $width = round( $pics_param[0] / $ratio ) ;
  • $height = $new_height ;
  • }
  • }
  • $image_mini = imagecreatetruecolor( $width, $height ) ;
  • ImageAlphaBlending( $image_mini, false );
  • ImageSaveAlpha( $image_mini, true );
  • imagecopyresampled( $image_mini, $this->_gdPics, 0, 0, 0, 0, $width, $height, $pics_param[0], $pics_param[1] ) ;
  • $this->_gdPics = $image_mini;
  • unset($image_mini);
  • $this->stack[] = array(__FUNCTION__, func_get_args());
  • return TRUE;
  • }
  • /**
  • * Rogne l'image courante de largeur $width_cropt et de hauteur $height_crop a l'endroit prédéfinie $flag, ou selon les
  • * coordonnées prédefinies ($x_origin, $y_origin) si $flag = custom
  • *
  • * @arguments STRING $image_saved nom de l'image à sauvegarder
  • * INT $width_crop taille en pixel de la largeur voulue finale
  • * INT $height_crop taille en pixel de la hauteur voulue finale
  • * CONT $flag TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTOM_RIGHT, BOTTOM, BOTTOM_LEFT, CENTER
  • * CUSTOM
  • * INT $x_origin Coordonée de l'origin x si $flag = CUSTOM
  • * INT $y_origin Coordonée de l'origin y si $flag = CUSTOM
  • *
  • * @return BOOL 1 En cas de succès sinon 0
  • */
  • public function crop( $width_crop, $height_crop, $flag = CENTER, $x_origin = '', $y_origin = '' ) {
  • if( $this->type === LOAD_FILE ) {
  • $pics_param = self::infos( $this->src ) ;
  • }
  • else {
  • $pics_param[0] = $this->width ;
  • $pics_param[1] = $this->height ;
  • }
  • if( $width_crop >= $pics_param[0] || $height_crop >= $pics_param[1] ) {
  • return FALSE ;
  • }
  • else {
  • $pictures_origin = self::open( $this->src ) ;
  • $image_mini = imagecreatetruecolor( $width_crop, $height_crop ) ;
  • if( $x_origin != '' && $y_origin != '' && $flag = CUSTOM ) {
  • ImageAlphaBlending( $image_mini, false );
  • ImageSaveAlpha( $image_mini, true );
  • imagecopyresampled( $image_mini, $this->_gdPics, 0, 0, $x_origin, $y_origin, $width_crop, $height_crop, $width_crop, $height_crop);
  • $this->_gdPics = $image_mini;
  • }
  • else {
  • static $x;
  • static $y;
  • switch ($flag) {
  • case TOP_LEFT:
  • $x = 0;
  • $y = 0;
  • break;
  • case TOP:
  • $x = ($pics_param[0] - $width_crop) / 2;
  • $y = 0;
  • break;
  • case TOP_RIGHT:
  • $x = ($pics_param[0] - $width_crop);
  • $y = 0;
  • break;
  • case RIGHT:
  • $x = ($pics_param[0] - $width_crop);
  • $y = ($pics_param[1] - $height_crop) / 2;
  • break;
  • case BOTTOM_RIGHT:
  • $x = ($pics_param[0] - $width_crop);
  • $y = ($pics_param[1] - $height_crop);
  • break;
  • case BOTTOM:
  • $x = ($pics_param[0] - $width_crop) / 2;
  • $y = ($pics_param[1] - $height_crop);
  • break;
  • case BOTTOM_LEFT :
  • $x = 0;
  • $y = ($pics_param[1] - $height_crop);
  • break;
  • case LEFT :
  • $x = 0;
  • $y = ($pics_param[1] - $height_crop) / 2;
  • break;
  • case CENTER :
  • $x = ($pics_param[0] - $width_crop) / 2;
  • $y = ($pics_param[1] - $height_crop) / 2;
  • break;
  • default :
  • throw new Exception ('Bad $flag, try : TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT, LEFT, CUSTOM');
  • break;
  • }
  • ImageAlphaBlending( $image_mini, false );
  • ImageSaveAlpha( $image_mini, true );
  • imagecopyresampled( $image_mini, $this->_gdPics, 0, 0, $x, $y, $width_crop, $height_crop, $width_crop, $height_crop);
  • $this->_gdPics = $image_mini;
  • unset($image_mini);
  • }
  • }
  • $this->stack[] = array( __FUNCTION__, func_get_args() );
  • return TRUE;
  • }
  • /**
  • * Applique un filtre $filtre sur l'image courante
  • *
  • * @arguments RESSOURCE $ressource une ressource image
  • * CONST $filtre IMG_FILTER_NEGATE Negatif de $pictures
  • * IMG_FILTER_GRAYSCALE Supprime les couleurs
  • * IMG_FILTER_BRIGHTNESS Luminosité de l'image
  • * INT $filtre_param_1 obligatoire 255 : Eclaircir l'image avec un maximum vers le blanc (effet de brillance)
  • * 0 : Couleurs inchangées
  • * -255 : Assombrir l'image au maximum vers le noir (effet sombre)
  • * IMG_FILTER_CONTRAST Contraste de l'image
  • * INT $filtre_param_1 obligatoire 255 : Eclaircir l'image avec un maximum vers le blanc (effet de brillance)
  • * 0 : Couleur inchangées
  • * -255 : Assombrir l'image au maximum vers le noir (effet sombre)
  • * IMG_FILTER_COLORIZE Modifie les tendances de couleurs (RGB)
  • * INT $filtre_param_1 obligatoire Valeur R [-255, 255]
  • * INT $filtre_param_2 obligatoire Valeur G [-255, 255]
  • * INT $filtre_param_3 obligatoire Valeur B [-255, 255]
  • * INT $filtre_param_4 obligatoire Valeur Alpha [-255, 255]
  • * IMG_FILTER_EDGEDETECT utilise la détection des bords pour les mettre en évidence dans l'image.
  • * IMG_FILTER_EMBOSS grave l'image en relief
  • * IMG_FILTER_GAUSSIAN_BLUR brouille l'image en utilisant la méthode gaussienne.
  • * IMG_FILTER_SELECTIVE_BLUR brouille l'image
  • * IMG_FILTER_MEAN_REMOVAL son utilisation signifie le déplacement pour réaliser un effet "peu précis"
  • * IMG_FILTER_SMOOTH rend l'image lissée (smooth). Utilisez le paramètre args1 pour définir le degré de lissoir [-8, 8]
  • * IMG_FILTER_PIXELATE applique un effet de pixelisation à l'image; utilise arg1 pour indiquer la taille de bloc, et arg2 pour indiquer le mode de pixelisation.
  • *
  • * @return BOOL 0 si une erreur est survenue
  • * RESOURCE images
  • */
  • public function filter( $filtre, $filtre_param_1 = '', $filtre_param_2 = '', $filtre_param_3 = '', $filtre_param_4 = '' ) {
  • switch( $filtre ) {
  • case IMG_FILTER_NEGATE :
  • case IMG_FILTER_GRAYSCALE :
  • case IMG_FILTER_EDGEDETECT :
  • case IMG_FILTER_EMBOSS :
  • case IMG_FILTER_GAUSSIAN_BLUR :
  • case IMG_FILTER_SELECTIVE_BLUR :
  • case IMG_FILTER_MEAN_REMOVAL :
  • $this->stack[] = array( __FUNCTION__,func_get_args() );
  • return imagefilter( $this->_gdPics, $filtre ) ;
  • break;
  • case IMG_FILTER_BRIGHTNESS :
  • case IMG_FILTER_CONTRAST :
  • case IMG_FILTER_SMOOTH :
  • $this->stack[] = array( __FUNCTION__,func_get_args() );
  • return imagefilter( $this->_gdPics, $filtre, $filtre_param_1 );
  • break;
  • case IMG_FILTER_COLORIZE :
  • $this->stack[] = array( __FUNCTION__,func_get_args() );
  • return imagefilter( $this->_gdPics, IMG_FILTER_CONTRAST, $filtre_param_1, $filtre_param_2, $filtre_param_3, $filtre_param_4 );
  • break;
  • case IMG_FILTER_PIXELATE :
  • $this->stack[] = array( __FUNCTION__,func_get_args() );
  • return imagefilter( $this->_gdPics, IMG_FILTER_PIXELATE, $filtre_param_1, $filtre_param_2 );
  • break;
  • case IMG_FILTER_SEPIA :
  • $this->stack[] = array( __FUNCTION__,func_get_args() );
  • imagefilter( $this->_gdPics, IMG_FILTER_GRAYSCALE );
  • return imagefilter( $this->_gdPics, IMG_FILTER_COLORIZE, 100, 50, 0);
  • break;
  • default :
  • return $this->_gdPics;
  • break;
  • }
  • }
  • /**
  • * Applique un masque d'opacité $mask sur l'image courante
  • * Attention $mask DOIT être une image PNG avec canal ALPHA (png 24 bits)
  • *
  • * @arguments RESSOURCE $pictures chemin d'accès d'une image
  • * $mask chemin d'accès d'une image png
  • * CONST $flag RESIZE_TO_PICTURES_SIZE Les dimensions de $mask seront adaptées aux dimensions de $pictures defaut
  • * RESIZE_TO_MASK_SIZE Les dimensions de $pictures seront adaptées aux dimensions de $mask
  • *
  • * @return BOOL 1 En cas de succès
  • *
  • * @throw EXCEPTION si $flag n'est pas reconnu
  • */
  • public function mask( $mask, $flag = RESIZE_TO_PICTURES_SIZE ) {
  • if( ( self::open( $mask ) ) === FALSE ) {
  • return FALSE;
  • }
  • else {
  • switch ($flag) {
  • case RESIZE_TO_PICTURES_SIZE :
  • $srcpicsproperties = array($this->width, $this->height);
  • $srcpics = $this->_gdPics;
  • imagealphablending ($srcpics, FALSE);
  • $srcoriginmask = self::open ( $mask );
  • $srcoriginmasksize = getimagesize( $mask );
  • $srcmask = imagecreatetruecolor ($srcpicsproperties[0], $srcpicsproperties[1]);
  • imagealphablending ( $srcmask, FALSE );
  • imagecopyresized ( $srcmask, $srcoriginmask, 0, 0, 0, 0, $srcpicsproperties[0], $srcpicsproperties[1], $srcoriginmasksize[0], $srcoriginmasksize[1]);
  • break;
  • case RESIZE_TO_MASK_SIZE :
  • $srcpicsproperties = getimagesize( $mask );
  • $srcpics = self::resize($this->_gdPics, $srcpicsproperties[0], $srcpicsproperties[1]);
  • $srcmask = self::open( $mask );
  • break;
  • default :
  • throw new Exception ('Bad $flag, try : RESIZE_TO_PICTURES_SIZE, RESIZE_TO_MASK_SIZE');
  • break;
  • }
  • }
  • for ($i=0; $i < $srcpicsproperties[0]; ++$i) {
  • for ($j=0; $j < $srcpicsproperties[1]; ++$j) {
  • $pxl_alpha = imagecolorsforindex ( $srcmask, imagecolorat ($srcmask, $i, $j));
  • $pxl_color = imagecolorsforindex ( $srcpics, imagecolorat ($srcpics, $i, $j));
  • $color = imagecolorallocatealpha (
  • $srcpics,
  • $pxl_color['red'],
  • $pxl_color['green'],
  • $pxl_color['blue'],
  • $pxl_alpha['alpha']);
  • imagesetpixel ($srcpics, $i, $j, $color);
  • }
  • }
  • $this->stack[] = array( __FUNCTION__, func_get_args() );
  • imagesavealpha ($srcpics, TRUE);
  • $this->_gdPics = $srcpics;
  • return TRUE;
  • }
  • /**
  • * Applique un pattern (motif) sur toute la surface de l'image
  • * Attention $pattern DOIT être une image PNG avec canal ALPHA (png 24 bits)
  • *
  • * @arguments $pattern chemin d'accès d'une image PNG
  • *
  • * @return BOOL 1 En cas de succès
  • *
  • * @throw EXCEPTION si $pattern n'est pas reconnu
  • */
  • public function pattern( $pattern ) {
  • if( $this->type == LOAD_FILE ) {
  • $pictures = $this->src ;
  • }
  • else {
  • $pictures = $this->_gdPics ;
  • }
  • if( !is_file( $pattern ) ) {
  • throw new Exception("Pattern $pattern not found.");
  • }
  • static $x = 0 ;
  • static $y = 0 ;
  • $propretiesSRC = array($this->width, $this->height);
  • $propretiesPattern = $this->infos( $pattern );
  • $nbrColumn = floor( $propretiesSRC[0] / $propretiesPattern[0] ) ;
  • $nbrRow = floor( $propretiesSRC[1] / $propretiesPattern[1] ) ;
  • try {
  • $temp = self::open( $pattern );
  • }
  • catch (exception $e) {
  • echo $e;
  • }
  • // Pour chaque ligne
  • for( $i = 0 ; $i <= $nbrRow ; $i++ ) {
  • for( $j = 0 ; $j <= $nbrColumn ; $j++ ) {
  • imagecopy( $this->_gdPics, $temp, $x, $y, 0, 0, $propretiesPattern[0], $propretiesPattern[1] );
  • $x += $propretiesPattern[0] ;
  • }
  • $x = 0;
  • $y += $propretiesPattern[1] ;
  • }
  • $this->stack[] = array( __FUNCTION__, func_get_args() );
  • return true;
  • }
  • /**
  • * Affiche l'image courante dans le naviguateur
  • *
  • * @arguments CONST $flag PNG
  • * JPEG
  • * JPG (alias JPEG)
  • * GIF
  • *
  • * @return RESOURCE images
  • */
  • public function display( $flag = PNG ) {
  • switch ( $flag ) {
  • case PNG:
  • header( 'Content-Type: image/' . $flag );
  • imagepng( $this->_gdPics );
  • imagedestroy( $this->_gdPics );
  • break;
  • case JPG:
  • header( 'Content-Type: image/jpeg' );
  • imagejpeg( $this->_gdPics );
  • imagedestroy( $this->_gdPics );
  • break;
  • case JPEG:
  • header('Content-Type: image/' . $flag);
  • imagejpeg($this->_gdPics);
  • imagedestroy($this->_gdPics);
  • break;
  • case GIF:
  • header('Content-Type: image/' . $flag);
  • imagegif($this->_gdPics);
  • imagedestroy($this->_gdPics);
  • break;
  • default:
  • header('Content-Type: image/' . $flag);
  • imagepng($this->_gdPics);
  • imagedestroy($this->_gdPics);
  • break;
  • }
  • }
  • /**
  • * Sauvegarde de la ressource image courante _gdPics sous forme de fichier $savedpictures au format $format de de qualité $quality
  • *
  • * @arguments CONST $format format de sortie de l'image, PNG, JPEG, JPG, GIF
  • *
  • * STRING $savedpictures Chemin d'accés pour l'image de sortie
  • *
  • * INT $quality Qualité de l'image de sortie (compression)
  • * PNG : 0 pas de compression à 9
  • * JPG : de 0 (pire qualité, petit fichier) et 100 (meilleure qualité, gros fichier)
  • * GIF : NULL
  • *
  • * @return BOOL 1 En cas de succès
  • *
  • * @throw EXCEPTION si $flag n'est pas reconnu
  • */
  • public function save( $format = PNG, $savedpictures = NULL, $quality = 5 ) {
  • if( is_null( $savedpictures ) ) {
  • throw new Exception ("Path $savedpictures is null, please specify target saved files.") ;
  • }
  • else {
  • $saved_pics_name = pathinfo( $savedpictures );
  • }
  • switch ( $format ) {
  • case PNG :
  • if( is_int( $quality ) && $quality >= 0 && $quality <= 9 ) {
  • imagepng($this->_gdPics, $saved_pics_name['dirname'] . '/' . self::name($savedpictures) . '.png', $quality);
  • return TRUE;
  • }
  • else {
  • return FALSE;
  • }
  • break;
  • case JPG :
  • case JPEG :
  • if( is_int($quality) && $quality >= 0 && $quality <= 100 ) {
  • imagejpeg($this->_gdPics, $saved_pics_name['dirname'] . '/' . self::name($savedpictures) . '.jpg', $quality);
  • return TRUE;
  • }
  • else {
  • return FALSE;
  • }
  • break;
  • case GIF :
  • if( imagegif( $this->_gdPics, $saved_pics_name['dirname'] . '/' . self::name($savedpictures) . '.gif' ) === TRUE ) {
  • return TRUE;
  • }
  • else {
  • return FALSE;
  • }
  • break ;
  • default :
  • throw new Exception ("Unknown format $format, please try PNG, JPG, GIF");
  • break ;
  • }
  • }
  • /**
  • * Sauvegarde des differents traitement éffectués sur l'image MAIS ne modifie pas l'image source.
  • *
  • * @arguments STRING $file Chemin d'un fichier pour sauvegarder les traitements
  • *
  • *
  • * @return BOOL 1 En cas de succès de la sauvegarde
  • *
  • * @throw EXCEPTION si $file n'est pas disponible en écriture
  • */
  • public function saveByActions( $file ) {
  • if ( !is_writable( $file ) && !fopen( $file , "w" ) ) {
  • throw new Exception("$file is not writable");
  • }
  • $string = "";
  • $compteur = 1;
  • foreach( $this->stack as $value ) {
  • $string.= serialize($value) . "\n";
  • ++$compteur;
  • }
  • $fp = fopen( $file, 'w+' );
  • fwrite( $fp, utf8_encode ( $string ) );
  • fclose( $fp );
  • return TRUE;
  • }
  • /**
  • * Charge une série de traitement à éffectués sur une image, ATTENTION le fichier sauvegardé DOIT
  • * être dans le même dossier que l'image source.
  • *
  • * @arguments STRING $path Chemin d'accès pour charger les traitements
  • *
  • *
  • * @return OBJECT Un nouvel objet Pics
  • *
  • */
  • public function loadByActions( $path ) {
  • $lines = file($path);
  • $compteur = 0;
  • foreach ($lines as $content) {
  • $temp = unserialize($content);
  • // Juste le nom de la méthode à appliquée
  • $methode = $temp[0];
  • array_shift($temp);
  • // Si ce n'est pas le constructeur
  • if( $compteur != 0 ) {
  • call_user_func_array( array($ret, $methode), $temp[0]);
  • }
  • // Si c'est le constructeur nous utilisons la reflectivité pour passer des arguments à la méthode __construct
  • // chose impossible avec call_user_func_array()
  • else {
  • // Les arguments doivent être sous forme de chaine et non pas de tableau
  • $callArgs = '';
  • foreach($temp as $args) {
  • $callArgs .= $args;
  • }
  • $reflect = new ReflectionClass( get_class() );
  • $ret = $reflect->newInstanceArgs( $args );
  • }
  • $compteur++;
  • }
  • return $ret;
  • }
  • /**
  • * Vide la pile de traitement de la ressource courante
  • */
  • public function reset() {
  • $this->stack = array();
  • }
  • }
  • ?>
<?php
/**
* Fichier à inclure inc.class.pics.php5
*
* LICENSE: Paternité Pas d'Utilisation Commerciale
*
* @category inc
* @package inc.class
* @subpackage inc.class.pics
* @copyright 2011 Inwebo
* @license http://creativecommons.org/licenses/by-nc-nd/2.0/fr/
* @version Mai 2011
* @link http://www.inwebo.net/
* @since Novembre 2009
*/ 


/**
 * Création et manipulation d'images
 *
 * Création et manipulation d'images grâce à la librairie GD2 et PHP5, attention pensez à activer GD2 !
 * Permet la manipulation d'image (rogner, filtres etc) et leur sauvegarde sans altérer le fichier source.
 *
 *
 * MIXED			__construct()					: 1 si instanciation réussie sinon lance exception
 * MIXED			newPics()						: Ressource si création de l'image réussie sinon lance exception
 * MIXED			open()							: Ressource si l'image est ouverte correctement sinon lance exception
 * STRING			name							: Retourne le nom d'un fichier sans son extension
 * ARRAY			info								: Retourne la largeur et la hauteur d'une image
 * MIXED			merge()							: 0 si les images n'existent pas, sinon renvoi la resource image de deux images fusionnées
 * MIXED			resize()							: 0 si les images n'existent pas, sinon renvoi la resource image redimensionnée
 * MIXED			crop()							: 0 si les images n'existent pas, sinon renvoi la resource image de deux images rognée
 * RESOURCE	filter()							: RESOURCE image avec un filtre appliqué
 * RESOURCE	mask()							: RESOURCE image avec un masque d'opacité appliqué sinon 0
 * RESOURCE	pattern()						: 1 si motif appliqué sur une image sinon exception
 * RESOURCE	display()						: Affiche une ressource image dans le navigateur
 * RESOURCE	imagecreatefrombmp()	: Création d'une ressource GD à partir d'une image au format BMP
 * BOOL			save()							: 1 si la sauvegarde s"est correctement déroulée, sauvegarde la ressource courante sous forme d'un fichier image
 * BOOL			saveByActions()			: Sauvegarde les traitements dans un fichier
 * BOOL			loadByActions()				: Charge des traitements
 * VOID				reset								: Vide la pile courante de traitement éffectués sur la ressource image
 * STRING			__tostring						: Infos sur l'objet courant
 */ 

/**
 * Définition des flags nécessaires.
 */
 	// Type
	define ('PNG', 'PNG');
	define ('JPEG', 'JPEG');
	define ('GIF', 'GIF');
	define ('JPG', 'JPEG');
	define ('BMP', 'BMP');

	// Palette
	define ('TRUE_COLOR', 'TRUE_COLOR');
	define ('INDEXED', 'INDEXED');

	// New filter
	define ('IMG_FILTER_SEPIA', 'IMG_FILTER_SEPIA');
	
	// Position CROP
	define ('TOP_LEFT','TOP_LEFT');
	define ('TOP', 'TOP');
	define ('TOP_RIGHT','TOP_RIGHT');
	define ('RIGHT', 'RIGHT');
	define ('BOTTOM_RIGHT', 'BOTTOM_RIGHT');
	define ('BOTTOM', 'BOTTOM');
	define ('BOTTOM_LEFT', 'BOTTOM_LEFT');
	define ('LEFT', 'LEFT');
	define ('CENTER', 'CENTER');
	define ('CUSTOM', 'CUSTOM');
	
	// Alpha
	define ('RESIZE_TO_MASK_SIZE', 'RESIZE_TO_MASK_SIZE');
	define ('RESIZE_TO_PICTURES_SIZE', 'RESIZE_TO_PICTURES_SIZE');
	
	// Save
	define ( 'NEW_FILE', 'NEW_FILE' );
	define ( 'REPLACE_FILE', 'REPLACE_FILE' );
	define ( 'STACK', 'STACK' );
	
	// Type instance
	define ( 'LOAD_FILE', 'LOAD_FILE');
	define ( 'NEW_GD', 'NEW_GD');

class Pics {
	
	// Ressource GD courante
	public $_gdPics;
	public $height;
	public $width;
	public $picsType;
	public $src;
	// Pile de traitement faits sur l'image courante
	public $stack;
	
	// getters
	public function getHeight() {
		return $this->height;
	}
		
	public function getWidth() {
		return $this->width;
	}
	
	public function getPicsType() {
		return $this->type;
	}
	
	public function getGdPics() {
		return $this->_gdPics;
	}
	
    /**
     * Instanciation de la class ouverture d'une image existante $nameOrLength
	 * Ou création d'une nouvelle ressource image de longueur $nameOrLength
	 * et de hauteur $height.
	 *
	 * @arguments	$nameOrLength	STRING	Chemin d'accès d'une image
	 *								INT		Largeur d'une nouvelle image
	 *
	 * @arguments	$height			NULL	Si $nameOrLength est une chaine
	 *								INT		Hauteur d'une nouvelle image
	 *
	 *
	 * @return    	TRUE		Si la nouvelle ressource image est crée avec succès
	 *
	 * @throw		EXCEPTION	Si $nameOrLength n'est pas un chemin d'accès valide
	 *							Ou si $nameOrLength et $height ne sont pas des entiers
     */
	public function __construct( $nameOrLength, $height = NULL ) {
		
		$this->stack = array();
	
		if ( !extension_loaded( 'gd' ) ) {
			throw new Exception('GD2 disabled');
		}
	  
		if( is_file( $nameOrLength ) && $height === NULL ) {	  
			$this->_gdPics 	= $this->open( $nameOrLength ) ;
			$this->src 		= $nameOrLength ;
			$this->type 	= LOAD_FILE ;
			$this->height	= imagesy($this->_gdPics) ;
			$this->width	= imagesx($this->_gdPics) ;
		}
		elseif( is_int( $nameOrLength ) && is_int( $height ) ) {
			// Demande une nouvelle ressource image
			$this->_gdPics	= $this->newPics( $nameOrLength, $height ) ;
			$this->width	= $nameOrLength ;
			$this->height	= $height ;
			$this->type 	= NEW_GD ;
		}
		else {
			throw new Exception('Missing ressource or pics doesn\'t exist');
		}
		$this->stack[] = array( __FUNCTION__, func_get_args() );
		return TRUE;
	  
	}
		
	/**
     * Créer une nouvelle ressource image, de largeur $largeur, de hauteur $hauteur, avec comme nombre de couleur
	 * $flag, de couleur RGB $R, $G, $B, et comme opacité $alpha
	 *
	 *
	 * @arguments 	INT $largeur, largeur en pixel
	 *				INT $hauteur, hauteur en pixel
	 *				STRING $flag DEFAULT TRUE_COLOR image 32 bits
	 * 									 INDEXED	image 1 bits
	 *				INT $alpha opacite 0 : opacite complete, 127 transparence complete
	 * @return    	RESOURCE images
     */
	public function newPics( $largeur, $hauteur, $flag = TRUE_COLOR, $R = '255', $G = '255', $B = '255', $alpha = '127' ) {
		switch ($flag) {
			case TRUE_COLOR :
					$pictures = imagecreatetruecolor($largeur, $hauteur);
					$fond 	  = imagecolorallocatealpha($pictures,  $R, $G, $B, $alpha);
					imagefill($pictures, 0, 0, $fond);
					imagesavealpha($pictures, true);
				break;
				
			case INDEXED :
					$pictures = imagecreate($largeur, $hauteur);
					$fond 	  = imagecolorallocatea($pictures,  $R, $G, $B);
					imagefill($pictures, 0, 0, $fond);
				break;
				
			default :
					throw new Exception ('Bad $flag, try : TRUE_COLOR, INDEXED');
				break;
		}
		$this->stack[] = array(__FUNCTION__, func_get_args() );
		return $pictures;	
	}	
	
	/**
     * Creation d'une ressource image gd
	 *
	 * @arguments 	STRING $pictures chemin d'accés à une image
	 * @return    	BOOL 0 si une erreur est survenuee
	 *				RESOURCE images
     */
	public function open( $pictures ) {
		if( !is_file($pictures) ) { return FALSE; }
		
		$pictures_param = $this->infos( $pictures );
		
		switch( $pictures_param['mime'] ) {
			case 'image/png' :
				return imagecreatefrompng($pictures);
				break;
				
			case 'image/jpeg' :
				return imagecreatefromjpeg($pictures);
				break;
			
			case 'image/gif' :
				return imagecreatefromgif($pictures);
				break;
				
			case 'image/x-ms-bmp' :
			case 'image/bmp' :
				return $this->imagecreatefrombmp($pictures);
				break;
			
			default :
				return FALSE;
				break;
		}
	}

	/**
     * Retourne une ressource GD à partir d'une image BMP
	 *
	 * @arguments 	STRING $filename chemin d'accés à l'image BMP
	 * @author		DHKold
	 * @url				http://www.php.net/manual/en/function.imagecreate.php#53879
	 * @thanks !
     */
	private function imagecreatefrombmp($filename) {
	// Ouverture du fichier en mode binaire
	if (! $f1 = fopen($filename,"rb")){ return FALSE; }

	//1 : Chargement des entêtes FICHIER
	$FILE = unpack( "vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread( $f1, 14 ) );
	if ($FILE['file_type'] != 19778){ return FALSE; }

	//2 : Chargement des entêtes BMP
   $BMP = unpack( 'Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
                 '/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
                 '/Vvert_resolution/Vcolors_used/Vcolors_important', fread( $f1, 40 ) );
	$BMP['colors'] = pow( 2, $BMP['bits_per_pixel'] );
	
	if ( $BMP['size_bitmap'] == 0 ) {
		$BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
	}
	
	$BMP['bytes_per_pixel']		=	$BMP['bits_per_pixel'] / 8;
	$BMP['bytes_per_pixel2']	=	ceil( $BMP['bytes_per_pixel'] );
	
	$BMP['decal']	= ( $BMP['width'] * $BMP['bytes_per_pixel'] / 4 );
	$BMP['decal']	-= floor( $BMP['width']*$BMP['bytes_per_pixel'] / 4 );
	$BMP['decal']	= 4 - ( 4 * $BMP['decal'] );
	
	if ( $BMP['decal'] == 4 ){
		$BMP['decal'] = 0;
	}

	//3 : Chargement des couleurs de la palette
	$PALETTE = array();
	if ( $BMP['colors'] < 16777216 && $BMP['colors'] != 65536 ) {
		$PALETTE = unpack('V' . $BMP['colors'], fread( $f1, $BMP['colors'] * 4 ) );	
	}

	//4 : Création de l'image
	$IMG	= fread( $f1, $BMP['size_bitmap'] );
	$VIDE	= chr( 0 );

	$res	= imagecreatetruecolor( $BMP['width'], $BMP['height'] );
	$P	= 0;
	$Y	= $BMP['height'] - 1;
	while ( $Y >= 0 ) {
		$X = 0;
		while ( $X < $BMP['width'] ) {
			if ($BMP['bits_per_pixel'] == 24) {
				$COLOR = unpack("V",substr($IMG,$P,3).$VIDE);
			}
			elseif ( $BMP['bits_per_pixel'] == 16 ) { 
				$COLOR		= unpack( "n", substr( $IMG, $P, 2 ) );
				$COLOR[1]	= $PALETTE[ $COLOR[1] + 1 ];
			}
			elseif ( $BMP['bits_per_pixel'] == 8 ) { 
				$COLOR		= unpack( "n", $VIDE . substr( $IMG, $P, 1 ) );
				$COLOR[1]	= $PALETTE[$COLOR[1]+1];
			}
			elseif ( $BMP['bits_per_pixel'] == 4 ) {
				$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
				if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F);
				$COLOR[1] = $PALETTE[$COLOR[1]+1];
			}
			elseif ( $BMP['bits_per_pixel'] == 1 ) {
				$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
				if(($P*8)%8 == 0) $COLOR[1] =  $COLOR[1]        >>7;
				elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6;
				elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5;
				elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4;
				elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3;
				elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2;
				elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1;
				elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1);
				$COLOR[1] = $PALETTE[$COLOR[1]+1];
			}
			elseif ($BMP['bits_per_pixel'] == 16) {
				$COLOR = unpack("v",substr($IMG,$P,2));
				$blue  = (($COLOR[1] & 0x001f) << 3) + 7;
				$green = (($COLOR[1] & 0x03e0) >> 2) + 7;
				$red   = (($COLOR[1] & 0xfc00) >> 7) + 7;
				$COLOR[1] = $red * 65536 + $green * 256 + $blue;
			}
			else { return FALSE; }
			imagesetpixel($res,$X,$Y,$COLOR[1]);
			$X++;
			$P += $BMP['bytes_per_pixel'];
		}
		$Y--;
		$P+=$BMP['decal'];
	}
	
	//Fermeture du fichier
	fclose($f1);
return $res;
}	
	
	/**
     * Retourne un nom de fichier $fichier sans son extension, utile pour PHP < 5.2.0
	 *
	 * @arguments 	STRING $fichier nom de fichier avec son extension
	 * @return    	STRING nom de fichier sans son extension
     */
	protected function name( $fichier ) {
		return basename ( $fichier, strrchr( $fichier, '.' ) );
	}
	
	/**
     * Renvoie les propriétés d'une image $pictures voir function getimagesize() 
	 * dans le manuel PHP
	 *
	 * @arguments 	STRING 	$pictures chemin d'accès à une image ou une ressource
	 * @return    	BOOL   	FALSE si une erreur est survenuee
	 * 						TRUE en cas de succès
     */
	protected function infos( $pictures ) {
		if( !is_resource($pictures) ) {
			return getimagesize( $pictures ) ;
		}
		else {
			$values["Width"]	= imagesx( $pictures );
			$values["Height"]	= imagesy( $pictures );
			return $values;
		}
		
	}
	
	/**
     * Copie une image $picturestomerge avec comme opacité $picturestomergeopacity dans la ressource GD
	 * courante dans une zone prédéfinie $flag avec une marge $margin , ou à l'endroit souhaité avec
	 * comme coordonnées ($x_origin, $y_origin).
	 *
	 * @arguments 	STRING 	$picturestomerge l'image à inserer dans $pictures
	 *				INT 	$picturestomergeopacity 0 : opaque, 127 transparent
	 *				CONST	$flag voir set_crop_pics()
	 *				INT		$x_origin coordonnée x de l'image à coller
	 *				INT		$y_origin coordonnée y de l'image à coller
	 *				INT		$margin marge souhaitée en pixel
	 * @return    	BOOL   	1 en cas de succès
	 *					   
     */
	public function merge( $picturestomerge, $flag = CENTER, $picturestomergeopacity = 99, $x_origin = NULL, $y_origin = NULL, $margin = NULL ) {
		// var_dump($picturestomerge);
		if( is_object( $picturestomerge ) ) {
			$pictures			 = $picturestomerge->_gdPics ;
			$picsToMergeWidth	 = $picturestomerge->getWidth();
			$picsToMergeHeight	 = $picturestomerge->getHeight();
		}
		elseif( is_string( $picturestomerge ) ) {
			$temp				 = new Pics($picturestomerge);
			$pictures			 = $temp->_gdPics;
			$picsToMergeWidth	 = $temp->getWidth();
			$picsToMergeHeight	 = $temp->getHeight();
		}
		elseif( is_resource( $picturestomerge ) ) {
			$pictures 			 = $picturestomerge;
			$picsToMergeWidth	 = imagesx($picturestomerge);
			$picsToMergeHeight	 = imagesy($picturestomerge);
		}

		static $x ;
		static $y ;
		
		switch ($flag) {

			case TOP_LEFT:
				$x = 0 + $margin;
				$y = 0 + $margin ;
				break;
						
			case TOP:
				$x = ($this->getWidth() - $picsToMergeWidth) / 2;
				$y = 0 + $margin;
				break;
						
			case TOP_RIGHT:
				$x = ($dest_im[0] - $src_im[0]) - $margin;
				$y = 0 - $margin;
				break;

			case RIGHT:
				$x = ($dest_im[0] - $src_im[0]) - $margin;
				$y = ($dest_im[1] - $src_im[1]) / 2;
				break;
						
			case BOTTOM_RIGHT:
				$x = ($dest_im[0] - $src_im[0]) - $margin;
				$y = ($dest_im[1] - $src_im[1]) - $margin;
				break;
							
			case BOTTOM:
				$x = ($dest_im[0] - $src_im[0]) / 2;
				$y = ($dest_im[1] - $src_im[1]) - $margin;
				break;
						
			case BOTTOM_LEFT :
				$x = 0 + $margin;
				$y = ($dest_im[1] - $src_im[1]) - $margin;
				break;
				
			case LEFT :
				$x = 0 + $margin;
				$y = ($dest_im[1] - $src_im[1]) / 2;
				break;

			case CENTER :
				$x = floor( ( $this->getWidth() - $picsToMergeWidth ) / 2);
				$y = floor( ( $this->getHeight() - $picsToMergeHeight ) / 2);
				break;
				
			case CUSTOM :
				$x = $x_origin;
				$y = $y_origin;
				break;
				
			default :
				throw new Exception ('Bad $flag, try : TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT, LEFT, CENTER, CUSTOM');
				break;			
		}
		
		imagecopymerge( $this->_gdPics, $temp->_gdPics, $x, $y, 0, 0, $picsToMergeWidth, $picsToMergeHeight , $picturestomergeopacity );
		
		$this->stack[] = array(__FUNCTION__, func_get_args() );
		unset($temp);
		return true;
	}
	
	/**
     * Redimensionne l'image courante, avec proportionalité sur la hauteur $new_width, largeur $new_height
	 * ou selon une taille prédéfinie ($new_width, $new_height)
	 *
	 * @arguments 	INT $new_width taille en pixel de la largeur voulue
	 *				INT $new_height taille en pixel de la hauteur voulue
	 *				
	 * @return    	BOOL 0 si une erreur est survenue
	 *				RESOURCE images
     */
	public function resize( $new_width = NULL, $new_height = NULL ) {
	
		if( $this->type == LOAD_FILE ) {
			$pics_param 		= self::infos( $this->src ) ;
			$pictures_origin	= self::open( $this->src ) ;
			// $pictures_origin	= $this->_gdPics ;
		}
		else {
			$pics_param[0] = $this->width ;
			$pics_param[1] = $this->height ;
			
		}
		
		// Resize fixed width and height
		if( isset( $new_width ) && isset( $new_height ) ) {
			$width  = $new_width;
			$height = $new_height;
		}
		// Resize by new width
		elseif( isset( $new_width ) && is_null( $new_height ) ) {
			// Ratio by width
			if( $new_width > $pics_param[0] ) {
				$ratio  = $new_width / $pics_param[0] ;
				$width  = $new_width ;
				$height = round( $pics_param[1] * $ratio ) ;
			}
			else {
				$ratio  = $pics_param[0] / $new_width  ;
				$width  = $new_width ;
				$height = round( $pics_param[1] / $ratio ) ;
			}
		}
		// Resize by new height
		elseif( isset( $new_height ) && is_null( $new_width ) ) {
			// Ratio by height
			if( $new_height > $pics_param[1] ) {
				$ratio  = $new_height / $pics_param[1] ;
				$width  = round( $pics_param[0] * $ratio ) ;
				$height = $new_height ;
			}
			else {
				$ratio  = $pics_param[1] / $new_height ;
				$width  = round( $pics_param[0] / $ratio ) ;
				$height = $new_height ;
			}
		}
		
		$image_mini 	= imagecreatetruecolor( $width, $height ) ;
		
		ImageAlphaBlending( $image_mini, false );
		ImageSaveAlpha( $image_mini, true );
		imagecopyresampled( $image_mini, $this->_gdPics, 0, 0, 0, 0, $width, $height, $pics_param[0], $pics_param[1] ) ;
		$this->_gdPics = $image_mini;
		unset($image_mini);
		$this->stack[] = array(__FUNCTION__, func_get_args());
		return TRUE;
	}
	
	/**
     * Rogne l'image courante de largeur $width_cropt et de hauteur $height_crop a l'endroit prédéfinie $flag, ou selon les
	 * coordonnées prédefinies ($x_origin, $y_origin) si $flag = custom
	 *
	 * @arguments 	STRING $image_saved nom de l'image à sauvegarder
	 *				INT $width_crop taille en pixel de la largeur voulue finale
	 *				INT $height_crop taille en pixel de la hauteur voulue finale
	 *				CONT $flag TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTOM_RIGHT, BOTTOM, BOTTOM_LEFT, CENTER
	 *							CUSTOM
	 *				INT $x_origin Coordonée de l'origin x si $flag = CUSTOM
	 *				INT $y_origin Coordonée de l'origin y si $flag = CUSTOM
	 *				
	 * @return    	BOOL 1 En cas de succès sinon 0
     */
	public function crop( $width_crop, $height_crop, $flag = CENTER, $x_origin = '', $y_origin = '' ) {

		if( $this->type === LOAD_FILE ) {
			$pics_param = self::infos( $this->src ) ;
		}
		else {
			$pics_param[0] = $this->width ;
			$pics_param[1] = $this->height ;
		}
		
			if( $width_crop >= $pics_param[0] || $height_crop >= $pics_param[1] ) {
				return FALSE ;
			}
			else {
			
				$pictures_origin = self::open( $this->src ) ;
				$image_mini 	 = imagecreatetruecolor( $width_crop, $height_crop ) ;
				
				if( $x_origin != '' && $y_origin != '' && $flag = CUSTOM ) {
						ImageAlphaBlending( $image_mini, false );
						ImageSaveAlpha( $image_mini, true );
						imagecopyresampled( $image_mini, $this->_gdPics, 0, 0, $x_origin, $y_origin, $width_crop, $height_crop, $width_crop, $height_crop);
						$this->_gdPics = $image_mini;
				}
				else { 
					static $x;
					static $y;
					
					switch ($flag) {

						case TOP_LEFT:
						$x = 0;
						$y = 0;
							break;
							
						case TOP:
						$x = ($pics_param[0] - $width_crop) / 2;
						$y = 0;
							break;
						
						case TOP_RIGHT:
						$x = ($pics_param[0] - $width_crop);
						$y = 0;
							break;

						case RIGHT:
						$x = ($pics_param[0] - $width_crop);
						$y = ($pics_param[1] - $height_crop) / 2;
							break;
						
						case BOTTOM_RIGHT:
						$x = ($pics_param[0] - $width_crop);
						$y = ($pics_param[1] - $height_crop);
							break;
							
						case BOTTOM:
						$x = ($pics_param[0] - $width_crop) / 2;
						$y = ($pics_param[1] - $height_crop);
							break;
							
						case BOTTOM_LEFT :
						$x = 0;
						$y = ($pics_param[1] - $height_crop);
							break;
							
						case LEFT :
						$x = 0;
						$y = ($pics_param[1] - $height_crop) / 2;
							break;
							
						case CENTER :
						$x = ($pics_param[0] - $width_crop) / 2;
						$y = ($pics_param[1] - $height_crop) / 2;
							break;
						
						default :
						throw new Exception ('Bad $flag, try : TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT, LEFT, CUSTOM');
							break;
					}
					
					ImageAlphaBlending( $image_mini, false );
					ImageSaveAlpha( $image_mini, true );
					imagecopyresampled( $image_mini, $this->_gdPics, 0, 0, $x, $y, $width_crop, $height_crop, $width_crop, $height_crop);
					$this->_gdPics = $image_mini;
					unset($image_mini);
				}
			}
		$this->stack[] = array( __FUNCTION__, func_get_args() );
		return TRUE;
	}
	
	/**
     * Applique un filtre $filtre sur l'image courante
	 *
	 * @arguments 	RESSOURCE $ressource une ressource image
	 *				CONST $filtre	IMG_FILTER_NEGATE		  Negatif de $pictures
	 *								IMG_FILTER_GRAYSCALE	  Supprime les couleurs
	 *								IMG_FILTER_BRIGHTNESS	  Luminosité de l'image
	 *									INT $filtre_param_1   obligatoire 255 	: Eclaircir l'image avec un maximum vers le blanc (effet de brillance)
	 *																	0		: Couleurs inchangées
	 *																	-255 	: Assombrir l'image au maximum vers le noir (effet sombre)
	 *								IMG_FILTER_CONTRAST		  Contraste de l'image
	 *									INT $filtre_param_1   obligatoire 255 	: Eclaircir l'image avec un maximum vers le blanc (effet de brillance)
	 *																	0		: Couleur inchangées
	 *																	-255 	: Assombrir l'image au maximum vers le noir (effet sombre)
	 *								IMG_FILTER_COLORIZE		  Modifie les tendances de couleurs (RGB)
	 *									INT $filtre_param_1   obligatoire Valeur R [-255, 255]
	 *									INT $filtre_param_2   obligatoire Valeur G [-255, 255]
	 *									INT $filtre_param_3   obligatoire Valeur B [-255, 255]
	 *									INT $filtre_param_4   obligatoire Valeur Alpha [-255, 255]
	 *								IMG_FILTER_EDGEDETECT	  utilise la détection des bords pour les mettre en évidence dans l'image.
	 *								IMG_FILTER_EMBOSS		  grave l'image en relief
	 *								IMG_FILTER_GAUSSIAN_BLUR  brouille l'image en utilisant la méthode gaussienne. 
	 *								IMG_FILTER_SELECTIVE_BLUR brouille l'image
	 *								IMG_FILTER_MEAN_REMOVAL   son utilisation signifie le déplacement pour réaliser un effet "peu précis"
	 *								IMG_FILTER_SMOOTH		  rend l'image lissée (smooth). Utilisez le paramètre args1  pour définir le degré de lissoir [-8, 8]
	 *								IMG_FILTER_PIXELATE		  applique un effet de pixelisation à l'image; utilise arg1  pour indiquer la taille de bloc, et arg2  pour indiquer le mode de pixelisation. 
	 *				
	 * @return    	BOOL 0 si une erreur est survenue
	 *				RESOURCE images
     */
	public function filter( $filtre, $filtre_param_1 = '', $filtre_param_2 = '', $filtre_param_3 = '', $filtre_param_4 = '' ) {
		switch( $filtre ) {
					
			case IMG_FILTER_NEGATE :
			case IMG_FILTER_GRAYSCALE :
			case IMG_FILTER_EDGEDETECT :
			case IMG_FILTER_EMBOSS :
			case IMG_FILTER_GAUSSIAN_BLUR :
			case IMG_FILTER_SELECTIVE_BLUR :
			case IMG_FILTER_MEAN_REMOVAL :
				$this->stack[] = array( __FUNCTION__,func_get_args() );
				return imagefilter( $this->_gdPics, $filtre ) ;
				break;
				
			case IMG_FILTER_BRIGHTNESS :
			case IMG_FILTER_CONTRAST :
			case IMG_FILTER_SMOOTH :
				$this->stack[] = array( __FUNCTION__,func_get_args() );
				return  imagefilter( $this->_gdPics, $filtre, $filtre_param_1 );
				break;
				
			case IMG_FILTER_COLORIZE :
				$this->stack[] = array( __FUNCTION__,func_get_args() );
				return imagefilter( $this->_gdPics, IMG_FILTER_CONTRAST, $filtre_param_1, $filtre_param_2, $filtre_param_3, $filtre_param_4 );
				break;
				
			case IMG_FILTER_PIXELATE :
				$this->stack[] = array( __FUNCTION__,func_get_args() );
				return imagefilter( $this->_gdPics, IMG_FILTER_PIXELATE, $filtre_param_1, $filtre_param_2 );
				break;
				
			case IMG_FILTER_SEPIA :
				$this->stack[] = array( __FUNCTION__,func_get_args() );
				imagefilter( $this->_gdPics, IMG_FILTER_GRAYSCALE );
				return imagefilter( $this->_gdPics, IMG_FILTER_COLORIZE, 100, 50, 0);
				break;
				
			default :
				return $this->_gdPics;
				break;
		}
		
	}

	/**
     * Applique un masque d'opacité $mask sur l'image courante
	 * Attention $mask DOIT être une image PNG avec canal ALPHA (png 24 bits)
	 *
	 * @arguments 	RESSOURCE $pictures chemin d'accès d'une image
	 * 						  $mask chemin d'accès d'une image png
	 *				CONST $flag RESIZE_TO_PICTURES_SIZE Les dimensions de $mask seront adaptées aux dimensions de $pictures defaut
	 *							RESIZE_TO_MASK_SIZE     Les dimensions de $pictures seront adaptées aux dimensions de $mask
	 *				
	 * @return    	BOOL 1 En cas de succès
	 *
	 * @throw EXCEPTION si $flag n'est pas reconnu
     */
	public function mask( $mask, $flag = RESIZE_TO_PICTURES_SIZE ) {
	
		if( ( self::open( $mask ) ) === FALSE ) {
			return FALSE;
		}
		
		else {
			switch ($flag) {
				case RESIZE_TO_PICTURES_SIZE :
					$srcpicsproperties = array($this->width, $this->height);
					$srcpics 		   = $this->_gdPics;
					imagealphablending ($srcpics, FALSE);					
					$srcoriginmask 	   = self::open ( $mask );
					$srcoriginmasksize = getimagesize( $mask );
					$srcmask 		   = imagecreatetruecolor ($srcpicsproperties[0], $srcpicsproperties[1]);
					imagealphablending ( $srcmask, FALSE );
					imagecopyresized ( $srcmask, $srcoriginmask, 0, 0, 0, 0, $srcpicsproperties[0], $srcpicsproperties[1], $srcoriginmasksize[0], $srcoriginmasksize[1]);
					break;
					
				case RESIZE_TO_MASK_SIZE :
					$srcpicsproperties = getimagesize( $mask );
					$srcpics 		   = self::resize($this->_gdPics, $srcpicsproperties[0], $srcpicsproperties[1]);
					$srcmask 		   = self::open( $mask );
					break;
					
				default :
					throw new Exception ('Bad $flag, try : RESIZE_TO_PICTURES_SIZE, RESIZE_TO_MASK_SIZE');
					break;
			}
		}
		
		for ($i=0; $i < $srcpicsproperties[0]; ++$i) {
			for ($j=0; $j < $srcpicsproperties[1]; ++$j) {
			$pxl_alpha = imagecolorsforindex ( $srcmask, imagecolorat ($srcmask, $i, $j));
			$pxl_color = imagecolorsforindex ( $srcpics, imagecolorat ($srcpics, $i, $j));
			$color 	= imagecolorallocatealpha (
					$srcpics,
					$pxl_color['red'],
					$pxl_color['green'],
					$pxl_color['blue'],
					$pxl_alpha['alpha']);
			imagesetpixel ($srcpics, $i, $j, $color);
			}
		}
		$this->stack[] = array( __FUNCTION__, func_get_args() );
		imagesavealpha ($srcpics, TRUE);
		$this->_gdPics = $srcpics;
		return TRUE;
	}
	
	/**
     * Applique un pattern (motif) sur toute la surface de l'image
	 * Attention $pattern DOIT être une image PNG avec canal ALPHA (png 24 bits)
	 *
	 * @arguments 	$pattern chemin d'accès d'une image PNG
	 *				
	 * @return    	BOOL 1 En cas de succès
	 *
	 * @throw EXCEPTION si $pattern n'est pas reconnu
     */
	public function pattern( $pattern ) {
		if( $this->type == LOAD_FILE ) {
			$pictures = $this->src ;
		}
		else {
			$pictures = $this->_gdPics ;
		}
		
		if( !is_file( $pattern ) ) {
			throw new Exception("Pattern $pattern not found.");
		}
		
		static $x = 0 ;
		static $y = 0 ;
		
		$propretiesSRC 		= array($this->width, $this->height);
		$propretiesPattern 	= $this->infos( $pattern );
		
		$nbrColumn 	= floor( $propretiesSRC[0] / $propretiesPattern[0] ) ;
		$nbrRow 	= floor( $propretiesSRC[1] / $propretiesPattern[1] ) ;
		
		try {
			$temp = self::open( $pattern );
		}
		catch (exception $e) {
			echo $e;
		}
		
		// Pour chaque ligne
		for( $i = 0 ; $i <= $nbrRow ; $i++ ) {

			for( $j = 0 ; $j <= $nbrColumn ; $j++ ) {
				imagecopy( $this->_gdPics, $temp, $x, $y, 0, 0, $propretiesPattern[0], $propretiesPattern[1] );
				$x += $propretiesPattern[0] ;
			}
			
			$x = 0;
			$y += $propretiesPattern[1] ;
		}
		$this->stack[] = array( __FUNCTION__, func_get_args() );
		return true;

	}


	
	/**
     * Affiche l'image courante dans le naviguateur
	 *
	 * @arguments 	CONST $flag PNG
	 *							JPEG
	 *							JPG (alias JPEG)
	 *							GIF
	 *				
	 * @return    	RESOURCE images
     */
	public function display( $flag = PNG ) {
		switch ( $flag ) {
			case PNG:
				header( 'Content-Type: image/' . $flag );
				imagepng( $this->_gdPics );
				imagedestroy( $this->_gdPics );
				break;
			
			case JPG:
				header( 'Content-Type: image/jpeg' );
				imagejpeg( $this->_gdPics );
				imagedestroy( $this->_gdPics );
				break;
				
			case JPEG:
				header('Content-Type: image/' . $flag);
				imagejpeg($this->_gdPics);
				imagedestroy($this->_gdPics);
				break;
				
			case GIF:
				header('Content-Type: image/' . $flag);
				imagegif($this->_gdPics);
				imagedestroy($this->_gdPics);
				break;
			
			default:
				header('Content-Type: image/' . $flag);
				imagepng($this->_gdPics);
				imagedestroy($this->_gdPics);
				break;
		}
	}

	/**
     * Sauvegarde de la ressource image courante _gdPics sous forme de fichier $savedpictures au format $format de de qualité $quality
	 *
	 * @arguments 	CONST $format format de sortie de l'image, PNG, JPEG, JPG, GIF
	 *
	 *				STRING $savedpictures Chemin d'accés pour l'image de sortie 
	 *
	 *				INT $quality Qualité de l'image de sortie (compression)
	 *						PNG : 0 pas de compression à 9
	 *						JPG : de 0 (pire qualité, petit fichier) et 100 (meilleure qualité, gros fichier)
	 *						GIF : NULL
	 *				
	 * @return    	BOOL 1 En cas de succès
	 *
	 * @throw EXCEPTION si $flag n'est pas reconnu
     */
	public function save( $format = PNG, $savedpictures = NULL, $quality = 5 ) {
		if( is_null( $savedpictures ) ) {
			throw new Exception ("Path $savedpictures is null, please specify target saved files.") ;
		}
		else {
			$saved_pics_name =  pathinfo( $savedpictures );
		}
		
		switch ( $format ) {
			case PNG :
				if( is_int( $quality ) && $quality >= 0 && $quality <= 9 ) {					
					imagepng($this->_gdPics, $saved_pics_name['dirname'] . '/' . self::name($savedpictures) . '.png', $quality);
					return TRUE;
				}
				else {
					return FALSE;
				}
				break;
				
			case JPG :
			case JPEG :
				if( is_int($quality) && $quality >= 0 && $quality <= 100 ) {
					imagejpeg($this->_gdPics, $saved_pics_name['dirname'] . '/' . self::name($savedpictures) . '.jpg', $quality);
					return TRUE;
				}
				else {
					return FALSE;
				}
				break;
				
			case GIF :
				if( imagegif( $this->_gdPics, $saved_pics_name['dirname'] . '/' . self::name($savedpictures) . '.gif' ) === TRUE ) {
					return TRUE;
				}
				else {
					return FALSE;
				}
				break ;
				
			default :
				throw new Exception ("Unknown format $format, please try PNG, JPG, GIF");
				
				break ;
		}
	}
	
	/**
     * Sauvegarde des differents traitement éffectués sur l'image MAIS ne modifie pas l'image source.
	 *
	 * @arguments 	STRING $file Chemin d'un fichier pour sauvegarder les traitements 
	 *
	 *				
	 * @return    	BOOL 1 En cas de succès de la sauvegarde
	 *
	 * @throw EXCEPTION si $file n'est pas disponible en écriture
     */
	public function saveByActions( $file ) {
		if ( !is_writable( $file ) && !fopen( $file , "w" ) ) {
			throw new Exception("$file is not writable");
		}
		$string   = "";
		$compteur = 1;
				
		foreach( $this->stack as $value ) {
			$string.= serialize($value) . "\n";
			++$compteur;
		}
		
		$fp = fopen( $file, 'w+' );
		fwrite( $fp, utf8_encode ( $string ) );
		fclose( $fp );
		return TRUE;
	}
	
	/**
     * Charge une série de traitement à éffectués sur une image, ATTENTION le fichier sauvegardé DOIT
	 * être dans le même dossier que l'image source.
	 *
	 * @arguments 	STRING $path Chemin d'accès pour charger les traitements 
	 *
	 *				
	 * @return    	OBJECT Un nouvel objet Pics
	 *
     */
	public function loadByActions( $path ) {
	
		$lines = file($path);
		$compteur = 0;
		
		foreach ($lines as $content) {
			$temp = unserialize($content);
			// Juste le nom de la méthode à appliquée
			$methode = $temp[0];
			array_shift($temp);

			// Si ce n'est pas le constructeur
			if( $compteur != 0 ) {
				call_user_func_array( array($ret, $methode),  $temp[0]);
			}
			// Si c'est le constructeur nous utilisons la reflectivité pour passer des arguments à la méthode __construct
			// chose impossible avec call_user_func_array()
			else {
				// Les arguments doivent être sous forme de chaine et non pas de tableau
				$callArgs = '';
				foreach($temp as $args) {
					$callArgs .= $args;
				}
				$reflect	= new ReflectionClass( get_class() );
				$ret		= $reflect->newInstanceArgs( $args );
			}
			$compteur++;
		}
		
		return $ret;
	}	

	/**
	 * Vide la pile de traitement de la ressource courante
	 */
	public function reset() {
		$this->stack = array();
	}

}
?>

 Conclusion

- Merci aKheNathOn & neigedhiver pour vos précieux conseils !

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

12 novembre 2009 00:24:24 :
- ajout de test.php5 avec des exemples d'utilisation. - documentation en ligne http://inwebo.free.fr/inc.class/pics/ - ajout d'une image
13 novembre 2009 22:52:26 :
- ajout de masque d'opacité, ajoutez des angles arrondis à vos images automatiquement par exemple. voir le fichier test.php5
20 août 2010 11:38:49 :
- Changement de l'organisation de la class - Réécriture de la plupart des fonctions - Ajout d'une fonction pour ajouter un motif sur une image - Ajout d'un nouveau filtre SEPIA
18 mai 2011 22:36:51 :
- Changement logique de la class, plus orienté objet. - Permet la sauvegarde des images après traitement sans modifier l'image source. - Limitation de la consomation mémoire (destruction d'objet inutile).
12 juin 2011 20:14:34 :
Ajout d'un dépôt de version sur github : https://github.com/inwebo/my.pics
17 juin 2011 00:23:09 :
- Support des images BMP - Suppression des anciennes images (droits), utilisation de mes travaux - Depôt GitHub, https://github.com/inwebo - Changement de l'encodage des fichiers -> UTF-8 sans BOM - Ajout fichier présentation

 Sources du même auteur

Source avec Zip MY.DEVIANTART API
Source avec Zip Source avec une capture MY.BOOKMARKS
Source avec Zip Source avec une capture MY.EXCEPTION
Source avec Zip MY.REMOTE : SERVEUR D'OBJETS PHP5
Source avec Zip Source avec une capture CSS-GENERATOR

 Sources de la même categorie

Source avec Zip GÉNÉRATION AUTOMATIQUE DE FICHIER .CLASS.PHP EN FONCTION D'U... par ig3
CLASSE D'OBJET DE CRYPTAGE ET DÉCRYPTAGE DE CHAINES DE CARAC... par 8Tnerolf8
Source avec Zip MY.DEVIANTART API par inwebo
CLASSE DE GESTION DE "VARIABLES GLOBALES D'ENVIRONNEMENT" par pifou25
Source avec Zip COLLECTION.CLASS.MIN.PHP par thunderhunter

 Sources en rapport avec celle ci

REDIMENSIONNEMENT D'IMAGE PHP par JStevens
Source avec une capture IMAGES GENETIQUES par coucou747
Source avec Zip CRÉATION D'UNE MINIATURE AVEC UNE LARGEUR OU UNE HAUTEUR MAX... par medium69
Source avec Zip Source avec une capture CLASSE DE MINIATURISATION D'IMAGES AVEC GD par guill76
Source avec Zip GÉNÉRATION AUTOMATIQUE DE BOUTON par Franquito

Commentaires et avis

Commentaire de twisteurwin le 12/11/2009 12:10:22 8/10

salut Inwebo c'est une très bonne source complète et utile merci de nous l'avoir partagée, si je vois des améliorations je posterai :)
merci bcp

Commentaire de inwebo le 12/11/2009 12:50:55

Au plaisir, merci d'avoir pris le temps d'y jeter un ½il !

Commentaire de aKheNathOn le 16/11/2009 09:22:43

Le sujet de ta source est très intéressant, et c'est agréable de voir que tout est bien documenté. Pas mal le côté filtre. J'ai une remarque qui pourrais changer ton code. Je constate que tu as fait une classe, ce qui est très bien, mais tu utilises des fonctions en passant en paramètres la ressource de l'image. Pour résumer, tu as fait une classe qui utilise l'astuce du pointeur de ressources dans les versions en mode fonctions.

Ma question / proposition serait de dire, autant faire une classe image, qui représente une image. A l'instanciation tu lui indiques soit un chemin, ce qui charge l'image, soit une taille, ce qui créé une image.

Du coup tu utiliserais toutes les fonctions sans avoir à passer le pointeur de la ressource image qui serait stocké dans l'instance de la classe.

Ce qui serait le top, serait d'avoir en complément des fonctions permettant de dessiner l'image.

Tu peux par exemple y mettre : du texte, des formes, des bouts d'images, bref des calques style photoshop, et ce n'est qu'au final en sauvegardant l'image au format png ou jpg ou gif que les pixels seraient dessinés. Entre temps tu stockerait tous les éléments dans ton instance de classe. D'autre part, ce serait pas mal du coup de faire une fonction d'enregistrement du contenu de la classe sous un fichier dans le style file_put_contents(serialize($this ...

En tout cas c'est une bonne base fonctionnelle, avec une orientation plus objet ce serait encore mieux.

Bonne prog, akh

Commentaire de neigedhiver le 16/11/2009 11:28:10

Salut,

private function get_gd_installed() {

Ta méthode est bizarrement faite... Pas vraiment optimisée.
Pourquoi ne pas utiliser, plus simplement, la fonction extension_loaded() qui sert justement à savoir si une extension particulière est chargée ?
D'une manière générale, pour ce genre de fonction, il est pertinent de ne pas réexécuter le code entier à chaque appel : autant stocker le résultat dans une variable statique et renvoyer celle-ci quand elle est définie. Exemple :

private function get_gd_installed() {
  static $flag = NULL;
  if (NULL !== $flag) {
    $flag = extension_loaded('gd');
  }
  return $flag;
}

Mais pour le cas présent, c'est superflu... Comme tu l'utilise dans dans ton constructeur, tu pourrais aussi bien te dispenser de cette méthode qui ne sert, en fait, à rien :

public function __construct() {
  if (!extension_loaded('gd')) {
    throw new Exception(_('GD disabled'));
  }
}

Là, j'utilise la fonction _(), alias de gettext qui permet de laisser l'utilisateur traduire le texte s'il le souhaite.

Ta méthode set_filters_pics pourrait gagner en clarté :

public function set_filters_pics($pictures, $filtre, $filtre_param_1 = '', $filtre_param_2 = '', $filtre_param_3 = '', $filtre_param_4 = '') {
if( !is_resource($pictures) ) {
$pictures = self::get_open_pics($pictures);
}
switch( $filtre ) {
case IMG_FILTER_NEGATE :
case IMG_FILTER_GRAYSCALE :
case IMG_FILTER_EDGEDETECT :
case IMG_FILTER_EMBOSS :
case IMG_FILTER_GAUSSIAN_BLUR :
case IMG_FILTER_SELECTIVE_BLUR :
case IMG_FILTER_MEAN_REMOVAL :
return (imagefilter($pictures, $filtre) !== FALSE);
break;
case IMG_FILTER_BRIGHTNESS :
case IMG_FILTER_CONTRAST :
case IMG_FILTER_SMOOTH :
return (imagefilter($pictures, $filtre, $filtre_param_1) !== FALSE);
break;
case IMG_FILTER_COLORIZE :
return (imagefilter($pictures, IMG_FILTER_CONTRAST, $filtre_param_1, $filtre_param_2, $filtre_param_3, $filtre_param_4) !== FALSE);
break;
case IMG_FILTER_PIXELATE :
return (imagefilter($pictures, IMG_FILTER_PIXELATE, $filtre_param_1, $filtre_param_2) !== FALSE);
break;
default:
return $pictures;
}
}


Bon la mise en page est pas géniale dans les commentaires...
Les idées sont :
- ta fonction renvoit le plus souvent un booléen, la fonction imagefilter aussi : inutile de faire un if pour tester et renvoyer un booléen... Utilise directement le résultat de la fonction imagefilter pour la valeur à renvoyer
- de nombreux cas nécessitent le même traitement : inutile de les séparer, autant les passer dans la même moulinette. La variable $filtre contient une valeur qui permet le traitement, puisqu'elle est "filtrée" par le bloc switch

D'une manière générale, tu pourrais économiser quelques lignes en factorisant un peu plus. Par exemple, les méthodes set_save_*_pics() qui font toutes la même chose pour chaque type d'image. Il serait intéressant d'avoir une certaine abstraction pour l'utilisateur, qu'il n'ait pas besoin absolument de connaître le type d'image pour appeler la bonne méthode : une seule méthode qui appellerait une méthode spécialisée en fonction du type d'image et avec certains paramètres selon ceux qui sont nécessaires.

L'idée d'Akh est à considérer sérieusement, c'est là qu'est la clé. Elle permettrait de faire de l'abstraction (avec atomisation du code), histoire de ne choisir le type d'image que quand on fait une conversion d'un type à un autre ou quand on enregistre l'image sur le disque, mais pas quand on la manipule.
Essaye aussi d'éviter le plus possible la redondance de code : quand deux fonctions ont le même code, à peu de choses près, autant les rassembler en une seule avec des paramètres, éventuellement avec deux fonctions spécialisées qui appellent la fonction "générique" avec les bons paramètres (ça évite aussi les entrées utilisateur qui peuvent provoquer des erreurs).

Voilà rapidement quelques conseils comme ça, sans avoir vraiment regardé le code en profondeur.

Commentaire de inwebo le 16/11/2009 15:51:16

AKH :

Ton idée de passer les paramètres lors de l'instanciation est tout simplement "logique". C'est une faute que je vais corriger dès que possible.
Pour les fonctions de dessins ou d'écriture sur l'image l'idée c'était de faire une class fille pour écrire sur l'image, et une pour ajouter des dessins (formes etc), et dans ce cas, la fonction image_set_filters n'a plus sa place dans la class Pictures. Je voulais juste éviter d'avoir une class monstre.

Par contre je n'ai pas compris l'idée de l'enregistrement du contenu de la class dans un fichier. Dans quel but ?

Neige :

Je ne connaissais tout simplement pas cette fonction (extension_loaded()), tu as entièrement raison, je corrige.
Je ne connaissais pas cette syntax pour le switch dans (image_set_filters() ). C'est plus propre et compact.
Effectivement pas besoin de re-tester les valeurs pour le return avec un if. Pour les fonctions set_save_*_pics, j'étais partis sur une unique fonctions, mais je me retrouve avec pas mal d'arguments, je voulais faire quelques chose de "simple" à utiliser, pour ne pas que l'utilisateur est à jongler avec trop de paramètres.

Et pour la mise en page des commentaires un peu moche je plaide non coupable (j'ai vu qu'il ne fallait pas dépasser les 120 caractères par ligne (dans la doc du zend framwork) mais je trouve cela un peu juste.

Je vais essayer de mettre en pratique tout cela.

J'ai une question, comment déclarer un alias de fonction ?
En tout cas merci à vous deux pour ces conseils avisés !

Commentaire de neigedhiver le 16/11/2009 23:04:31

En PHP, on ne peut pas déclarer d'alias de fonction... Pour ma part, j'ignorais que c'était possible dans d'autres langagtes (en fait, je ne m'étais jamais posé cette question).
En quoi est-ce que ça consiste exactement ?

Pour la mise en forme, je parlais de mon code à moi que j'ai posté : dans les commentaires, il s'affiche sans indentation.
En python, les recommandations sont de ne pas dépasser les 80 caractères, retour à la ligne compris. La raison : pour éditer un script en ligne de commande (avec VI par exemple), on ne perd pas l'indentation et la lisibilité du code. Cela implique que Python fournit une syntaxe spécifique pour "écrire une ligne sur plusieurs lignes". Bref, on s'égare.

Ce que voulais dire Akh c'est de ne pas utiliser le pointeur comme argument pour chaque méthode. Au lieu de ça, il faut considérer une instance de la classe comme un objet image que l'on manipule grâce à ses méthodes.
En gros, lors de l'instanciation de la classe, deux cas peuvent se présenter :
- on "charge" une image
- on crée une nouvelle image

Dans le premier cas, il convient d'accéder au fichier et d'en faire une image GD. Il faut alors stocker dans une propriété (par exemple $this->gd_image) le pointeur vers cette image GD. A partir de là, l'instance de cette classe ne manipule plus que cette image.
Dans le second, on crée simplement une image GD dont on stocke le pointeur dans ladite propriété.
Quand une méthode nécessite de manipuler le pointeur, elle utilise simplement $this->gd_image. Inutile de passer le pointeur en argument : c'est une tâche dont l'utilisateur de ta classe devrait être soulagé.
J'espère avoir été clair, sinon, il faudra un exemple de code ^^

Commentaire de inwebo le 17/11/2009 12:22:27

Pour l'alias, j'ai fait l'erreur d'inattention d'écrire set_save_jpg_pics au lieu de set_save_jpeg_pics, et je me suis demandé si il n'y avait pas possibilité de faire un alias sans re-écrire toute la fonction. Car cela pourrait être une erreur courante d'utilisation.

Oui Neige après relecture tu parlais bien de tes commentaires. ^^
Sinon 80 caractères par ligne, mais 120 tolérés.

http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html#coding-standard.php-file-formatting.max-line-length

Sinon, j'avais compris l'idée d'AKH, pour l'instanciation de la class, de passer en paramètre, soit un chemin, soit des dimensions , c'est juste cela qui m'avait posé problème :

"D'autre part, ce serait pas mal du coup de faire une fonction d'enregistrement du contenu de la classe sous un fichier dans le style file_put_contents(serialize($this ..."

Commentaire de neigedhiver le 17/11/2009 12:44:59

Ah d'accord ok d'accord.
L'idée est simplement de linéariser la classe (ou plus exactement une instance de la classe) et de l'enregistrer sous cette forme dans un fichier. Ca te permet, d'une certaine manière d'avoir ton format d'image "propriétaire", propre à ta classe. Ainsi, pour ouvrir un "fichier image" de ta classe, il suffirait d'une méthode statique qui délinéariserait le contenu du fichier et le retournerait en tant qu'instance de la classe, restaurant ainsi l'instance précédemment enregistrée avec toutes ses propriétés (donc, a priori, y compris l'image GD stockée dans une propriété).
La seule question que je me pose est : peut-on linéariser une image GD ? A creuser...
Ou alors, j'ai rien compris à ce que disait Akh...

Commentaire de aKheNathOn le 17/11/2009 13:23:06

T'as raison neige, c'est à quoi je pensait. L'idée est de faire un script de retouche d'images, or quand tu sauvegarde l'image en jpg ou PNG tu ne peux plus revenir sur une modification du/des filtres ou bien de sa composition si tu y incruste plusieurs images.

Il faut donc en plus de l'image de pouvoir enregistrer les filtres et les infos de ta classe et garder les ressources d'origine.

Du coup tu sauvegarde ton image au format sérialisé de la classe. Plus tard, tu peux re-ouvrir ton fichier sérialisé comme indique neige,
y modifier des paramètres de blur ou autre puis tu peux ré-exporter l'image au format que tu veux...

Parcontre à coup sûr le pointeur d'instance GD ne sera pas bon, il faudra le ré-ouvrir lors de la déserialisation. Si tu veux tu peux aller à fond dans le truc ... tu te fait une classe qui représente le ptr GD. En constructeur lui passes soit un fichier ou une taille, il initialize le pointeur GD.

1 - Si c'est un fichier tu mets le contenu de celui-ci dans une propriété de la classe.
2 - Si c'est un nouveau fichier, tu mets width et height ...

Lors de la désérialisation, tu vérifies si :

1 - Contenu du fichier dans la classe, dans ce cas tu l'enregistres dans un temporaire et tu initialise GD à partir de
2 - Sinon construire une nouvelle instance.

Du coup en sérialisant, tu stockes dans ton fichier la structure et paramétrage de ta transformation sur l'image, ainsi que les contenus. Le format serait alors distribuable en tant que tel.

C'est peut-être un peu compliqué mais ça serait pratique pour faire des modifs à la volée sans avoir besoin d'un bloc de code pour instancier et configurer les filtres.

Bonne prog,
akh

Commentaire de inwebo le 17/11/2009 14:14:51

Compris et très bonne idée. Cela serait d'ailleurs une valeurs ajoutée par rapport aux autres class qui font peu ou proue la même chose. Plutôt que de réinventer la roue autant lui mettre de nouveaux pneus (image naze mais c'est tout ce que j'avais sous la main....... désolé).

Merci à vous deux en tout cas !

Commentaire de aKheNathOn le 22/05/2010 22:16:08

Salut Inwebo,

Je compte utiliser ton code dans un de mes projets :) que je vais le distribuer en GPL / je pense que ça doit être compatible avec ta licence.

Je te propose que j'y apporte également quelques améliorations que tu pourrais publier en mise à jour à cette source si tu le souhaite.

Je te tiens au courant,
akh

Commentaire de inwebo le 24/05/2010 12:14:36

Okay,

Pas de problème, par curiosité quel est ton projet ?
Je mettrais à jour sur phpcs.

Bon prog'

Commentaire de aKheNathOn le 25/05/2010 09:30:59

J'ai explosé ta classe en plein de classes annexes comme je l'ai expliqué dans mes commentaires, du coup ça ne ressemble plus trop à la classe de départ, parcontre je n'ai pas toutes tes fonctionnalités ce qui est un peu dommage (je pense aux masques notamment)... reste encore à finaliser mais pour mon projet j'ai ce qu'il me faut : redimensionnement des vignettes.

Le projet qui est en cours de réalisation et un système de gestion eCommerce tout ce qu'il y a de plus classique, dès que j'aurais une version beta je le mettrais sur un SVN pour partager le code - je te tiendrais au courant

Commentaire de inwebo le 19/05/2011 13:57:10

Pour neigedhiver,

La seul chose que l'on ne peut sérialiser en PHP c'est les données de type ressources :

"The value to be serialized. serialize() handles all types, except the resource-type. You can even serialize() arrays that contain references to itself. Circular references inside the array/object you are serializing will also be stored. Any other reference will be lost. "

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

générer des miniatures avec gd 1.6 [ par vegetaline ] muhaha alors là c'est rigolo, un super défi pour les programmeurs fous!ok j'ai le code pour générer des miniatures grâce au php, mais ça marche qu'ave Images miniatures par scrollbar [mysql] [ par csosiris ] Bonjour, je voudrais savoir comment faire un "diaporama" d'image en passant par leur lien, range dans une bd mysql.Les images seraient affichees en li Pb de miniatures avec des images lourdes [ par tinos26 ] Bonjour, voila j'ai mis en place un site dynamique qui affiche &#224; la vol&#233;e des photos.Celle-ci avant d'etre telecharg&#233;es par les users, [BLOB->GD] Redimensionner un "flux image binaire"... [ par arnal69130 ] Bonjour &#224; tous,Je cherche &#224; faire une page pour afficher la carte d'identit&#233; d'un "agent", pour simplifier disons juste son nom et sa p comment redimensionner à la volée des images grâce à la lib GD ??? [TITRE MODERE CAR BOURRE DE FAUTES] [ par fredericmaill ] Bonjour, j'aimerais savoir comment redimention&#233; a la voll&#233; des images, donc j'aimerais savoir quelle fonction de la lib gd utiilis&#233; !! création de miniatures à partir d'une bdd [ par fornatus ] Bonjour j'aimerais connaitre le code permettant de créer une galerie de miniatures d'images (256*192 px, 5images par lignes) à partir d'images dont le Problème avec GD sur mon serveur [ par rastajeff ] Bonjour, je travaille actuellement sur un projet Flex/PHP et je rencontre une erreur bizarre. Je fais un upload et redimensionnement d'images, tout ce Pb avec la lib GD [ par quentin2b ] Bonjour a tous,Je cherchais un petit script pour protéger des images sur un de mes sites masi voila je rencontre un pb avec le code sources que j'ai t redimmensionner des images ... [ par loupile ] Bonjour, je vous explique sur mon site j'affiche des images hebergées sur des serveurs distants ... donc pas sur le mien :-) je voudrais pouvoir rédui gd et la superposition d'images transparentes [ par bizu29 ] Tout d'abord bonjour/soirAlors j'ai un petit soucis qui commence a me rendre dingue Mon but est de fusionner ces 2 images avec gd <img src="http://biz


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,515 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales