Return to Snippet

Revision: 19628
at October 27, 2009 13:55 by FlYos


Initial Code
<?php
/**
  * ImageText class, class.generatorimagetext.php
  * Module Stickers Custom Text
  * @category classes
  *
  * @author Steven Titren <[email protected]>
  * @copyright webaki.com
  *
  */
  
class ImageText
{
    /**
     * La largeur de l'image
     * @var int
     * @access protected
     */
    protected $_width;
    
    /**
     * La hauteur de l'image
     * @var int
     * @access protected
     */
    protected $_height;
    
    /**
     * Le chemin vers la police à utiliser
     * @var string
     * @access protected
     */
    protected $_font;
    
    /**
     * La taille de la police (en pt)
     * @var int
     * @access protected
     */
    protected $_fontSize;
    
    /**
     * La couleur du texte en RGB
     * @var array
     * @access protected
     */
    protected $_textColor;
    
    /**
     * La couleur du fond en RGB
     * @var array
     * @access protected
     */
    protected $_bgColor;
    
    /**
     * Le nombre de point par pouce (dot per inch)
     * @var int
     * @access protected
     */
    protected $_dpi = 72;
    
    /**
     * Le texte à afficher dans l'image
     * @var string
     * @access protected
     */
    protected $_string;
    
    /**
     * Le flux de l'image créé
     * @var resource
     * @access protected
     */
    protected $_img;
    
    /**
     * La position du texte sur l'axe x
     * @var int
     * @access protected
     */
    protected $_posX;
    
    /**
     * La position du texte sur l'axe y
     * @var int
     * @access protected
     */
    protected $_posY;
    
    /**
     * Enregistre les valeurs possible pour les position sur l'axe x
     * @var array
     * @access protected
     */
    protected $_posXlitteral = array('left', 'center', 'right');
    
    /**
     * Enregistre les valeurs possible pour les position sur l'axe y
     * @var array
     * @access protected
     */
    protected $_posYlitteral = array('top', 'middle', 'bottom');
    
    /**
     * Constructeur
     * @param  string  $string     La texte à afficher dans l'image
     * @param  int     $width      La largeur de l'image
     * @param  int     $height     La hauteur de l'image
     * @param  string  $font       Le chemin vers la police d'écriture à utiliser
     * @param  int     $fontSize   La taille de la police
     * @param  array   $textColor  La couleur du texte
     * @param  array   $bgColor    La couleur de fond de l'image
     * @param  int     $dpi        Le nombre de point par pouce (dot per inch)
     * @return void
     */
    public function __construct (
        $string=null, 
        $width=null, $height=null, 
        $font=null, $fontSize=null, 
        $textColor=array(), $bgColor=array(),
        $dpi = null
    )
    {
        if($string!=null)
            $this->setString($string);
        
        if($width!=null)
            $this->setWidth($width);
        
        if($height!=null)
            $this->setHeight($height);
        
        if($font!=null)
            $this->setFont($font);
        
        if($fontSize!=null)
            $this->setFontSizeInPx($fontSize);
        
        if(is_array($textColor))
        {
            if(count($textColor)>0)
                $this->setTextColorRGB($textColor);
        }
        else
        {
            if($textColor!=null)
                $this->setTextColorHexa($textColor);
        }
        
        if(is_array($bgColor))
        {
            if(count($bgColor)>0)
                $this->setBgColorRGB($bgColor);
        }
        else
        {
            if($bgColor!=null)
                $this->setBgColorHexa($bgColor);
        }
        
        if($dpi!=null)
            $this->setDpi($dpi);
            
        $this->setPosition('center middle');
    }
    
    /**
     * Récupérer le taille du texte
     * @return array La largeur et la hauteur de la police en pixel
     */
    public function getTextSizePX()
    {        
        $bbox = $this->_getBBox();
        
        if(!$bbox)
            return false;
        
        $w = intval(abs($bbox[2] - $bbox[0]));
        $h = intval(abs($bbox[7] - $bbox[1]));
        
        return array('width'=>$w, 'height'=>$h);
    }
    
    /**
     * Récupérer le taille du texte
     * @return array La largeur et la hauteur de la police
     */
    public function getTextSizeCm()
    {        
        $sizePX = $this->getTextSizePX();
        
        if(!$sizePX)
            return false;
        
        $w = self::convertPxInCm($sizePX['width']);
        $h = self::convertPxInCm($sizePX['height']);
        
        return array('width'=>$w, 'height'=>$h);
    }
    
    /**
     * Retourne la superfie du texte
     * @return float
     */
    public function calculateArea()
    {
        $size = $this->getTextSizeCm();
        
        if(!$size)
            return false;
        
        return ($size['width']/100) * ($size['height']/100);
    }
    
    /**
     * Contruit l'image sans l'afficher
     * @return boolean
     */
    public function buildStream()
    {
        if(!$this->_isReady())
            return $this->_reportError(__METHOD__, __LINE__, 'Le générateur manque d\'information pour continuer.');
        
        $this->_img = imagecreatetruecolor($this->_width, $this->_height);
        
        if(!$this->_img)
            return false;
        
        $bgColor   = imagecolorallocate($this->_img, $this->_bgColor[0], $this->_bgColor[1], $this->_bgColor[2]);
        $textColor = imagecolorallocate($this->_img, $this->_textColor[0], $this->_textColor[1], $this->_textColor[2]);
        
        imagefilledrectangle($this->_img, 0, 0, ($this->_width-1), ($this->_height-1), $bgColor);
        
        imagefttext($this->_img, $this->_fontSize, 0, $this->_posX, $this->_posY, $textColor, $this->_font, $this->_string);
        
        return true;
    }
    
    /**
     * Affiche l'image
     * @return void
     */
    public function displayImage()
    {
        header('Content-type: image/png');
        imagepng($this->_img);
        imagedestroy($this->_img);
    }
    
    public function saveImage($filename)
    {
        imagepng($this->_img, $filename);
        imagedestroy($this->_img);
    }
    
    /**
     * Vérifie que le générateur à toute les informations
     * @return boolean
     */
    public function _isReady()
    {
        if(strlen($this->_string)<=0)
            return false;
        
        if($this->_width<=0)
            return false;
        
        if($this->_height<=0)
            return false;
        
        if(!$this->checkFontFile())
            return false;
        
        if($this->_fontSize<=0)
            return false;
        
        if(!self::checkColorRGG($this->_textColor))
            return false;
        
        if(!self::checkColorRGG($this->_bgColor))
            return false;
        
        if($this->_dpi<=0)
            return false;
        
        if($this->_posX<0 || $this->_posX>=$this->_width)
            return false;
        
        if($this->_posY<0 || $this->_posY>=$this->_height)
            return false;
            
        return true;
    }
    
    
  /****************/
  /***  SETTER  ***/
  /****************/
    
    
    /**
     * Changer le texte à afficher
     * @param  string  $string  La texte à afficher dans l'image
     * @return boolean
     */
    public function setString($string)
    {
        $this->_string = trim($string);
        
        if(strlen($this->_string)<=0)
            return $this->_reportError(__METHOD__, __LINE__, 'La chaine de caractère ne doit pas être vide.');
        
        return true;
    }
    
    /**
     * Changer la largeur de l'image
     * @param  int  $width  La largeur de l'image
     * @return boolean
     */
    public function setWidth($width)
    {
        $width = intval($width);
        
        if($width<=0)
            return $this->_reportError(__METHOD__, __LINE__, 'La largeur de l\'image doit être strictement supérieur à 0px');
        
        $this->_width = $width;
        return true;
    }
    
    /**
     * Changer la hauteur de l'image
     * @param  int  $width  La hauteur de l'image
     * @return boolean
     */
    public function setHeight($height)
    {
        $height = intval($height);
        
        if($height<=0)
            return $this->_reportError(__METHOD__, __LINE__, 'La hauteur de l\'image doit être strictement supérieur à 0px');

        $this->_height = $height;
        return true;
    }
    
    /**
     * Changer le chemin de la police d'écriture
     * @param  string  $font  La police d'écriture
     * @return boolean
     */
    public function setFont($font)
    {
        if(!is_file($font))
            return $this->_reportError(__METHOD__, __LINE__, 'Le fichier de la police n\'existe pas.');
            
        $this->_font = trim($font);
        return true;
    }
    
    /**
     * Changer la taille de la police
     * @param  int  $fontSize  La taille de la police en pixel
     * @return boolean
     */
    public function setFontSizeInPx($fontSize)
    {
        $fontSize = intval($fontSize);
        
        if($fontSize<=0)
            return $this->_reportError(__METHOD__, __LINE__, 'La taille de la police doit être strictement supérieur à 0px');
        
        $this->_fontSize = $fontSize;
        return true;
    }
    
    /**
     * Changer la taille de la police
     * @param  int  $fontSize  La taille de la police en cm
     * @return boolean
     */
    public function setFontSizeInCm($fontSize)
    {
        $fontSize = intval($fontSize);
        
        if($fontSize<=0)
            return $this->_reportError(__METHOD__, __LINE__, 'La taille de la police doit être strictement supérieur à 0px');
        
        $this->_fontSize = self::convertCmInPx($fontSize, $this->_dpi);
        return true;
    }
    
    /**
     * Changer la couleur du texte
     * @param  array  $color  La couleur du texte en RGB
     * @return boolean
     */
    public function setTextColorRGB($color)
    {
        if(!self::checkColorRGG($color))
            return $this->_reportError(__METHOD__, __LINE__, 'Couleur RGB invalide');
        
        $this->_textColor = $color;
        return true;
    }
    
    /**
     * Changer la couleur du texte
     * @param  string  $color  La couleur du texte en hexadecimal
     * @return boolean
     */
    public function setTextColorHexa($color)
    {
        $colorRGB = self::colorHexaToRGB($color);
        
        return ($colorRGB!==false) ? $this->setTextColorRGB($colorRGB) : false;
    }
    
    /**
     * Changer la couleur du fond
     * @param  array  $color  La couleur du fond en RGB
     * @return boolean
     */
    public function setBgColorRGB($color)
    {
        if(!self::checkColorRGG($color))
            return $this->_reportError(__METHOD__, __LINE__, 'Couleur RGB invalide');
        
        $this->_bgColor = $color;
        return true;
    }
    
    /**
     * Changer la couleur du fond
     * @param  string  $color  La couleur du fond en hexadecimal
     * @return boolean
     */
    public function setBgColorHexa($color)
    {
        $colorRGB = self::colorHexaToRGB($color);
        
        return ($colorRGB!==false) ? $this->setBgColorRGB($colorRGB) : false;
    }
    
    /**
     * Changer le nombre de ppp (ou dpi)
     * @param  int  $dpi  Le nombre de ppp (ou dpi)
     * @return boolean
     */
    public function setDpi($dpi)
    {
        $dpi = intval($dpi);
        
        if($dpi<0)
            return $this->_reportError(__METHOD__, __LINE__, 'Le nombre de point par pour (dot per inch) doit être strictement supérieur à 0.');
        
        $this->_dpi = $dpi;
        return true;
    }
    
    /**
     * Change la position du texte en X
     * @param  int  $posX  La position en X
     * @return boolean
     */
    public function setPosX($posX)
    {
        $posX = intval($posX);
        
        if($posX<0)
            return $this->_reportError(__METHOD__, __LINE__, 'La position en x doit être strictement supérieur à 0.');
        
        $this->_posX = $posX;
        return true;
    }
    
    /**
     * Change la position du texte en Y
     * @param  int  $posY  La position en Y
     * @return boolean
     */
    public function setPosY($posY)
    {
        $posY = intval($posY);
        
        if($posY<0)
            return $this->_reportError(__METHOD__, __LINE__, 'La position en y doit être strictement supérieur à 0.');
        
        $this->_posY = $posY;
        return true;
    }
    
    /**
     * Permet de spécifier la position du texte de façon littéral
     * <p>
     * Valeur possible: <br />
     * left top
     * left middle
     * left bottom
     * center top
     * center middle
     * center bottom
     * right top
     * right middle
     * right bottom
     * </p>
     * @param  string  $pos  La position du texte. 
     */
    public function setPosition($pos = 'left top')
    {
        $pos = explode(' ', $pos);
        if(count($pos)!=2)
            return $this->_reportError(__METHOD__, __LINE__, 'Merci de spécifie une position sur x et sur y.');
        
        $pos1 = trim($pos[0]);
        $pos2 = trim($pos[1]);
        
        if(in_array($pos1, $this->_posXlitteral))
        {
            $x = $this->_gePositionX($pos1);
            $y = $this->_gePositionY($pos2);
        }
        else
        {
            $x = $this->_gePositionX($pos2);
            $y = $this->_gePositionY($pos1);
        }
        
        if($x===false || $y===false)
            return false;
        
        $this->_posX = $x;
        $this->_posY = $y;
        
        return true;
    }
    
    
  /****************/
  /***  GETTER  ***/
  /****************/
    
    
    /**
     * Récupérer le texte
     * @return string
     */
    public function getString()
    {
        return $this->_string;
    }
    
    /**
     * Récupérer la largeur de l'image
     * @return int
     */
    public function getWidth()
    {
        return $this->_width;
    }
    
    /**
     * Récupérer la hauteur de l'image
     * @return int
     */
    public function getHeight()
    {
        return $this->_height;
    }
    
    /**
     * Récupérer le chemin de la police d'écriture utilisé
     * @return string
     */
    public function getFont()
    {
        return $this->_font;
    }
    
    /**
     * Récupérer la taille de la police en px
     * @return int
     */
    public function getFontSizeInPx()
    {
        return $this->_fontSize;
    }
    
    /**
     * Récupérer la taille de la police en cm
     * @return int
     */
    public function getFontSizeInCm()
    {
        return self::convertPxInCm($this->_fontSize, $this->_dpi);
    }
    
    /**
     * Récupérer la couleur RGB du texte
     * @return array
     */
    public function getTextColorRGB()
    {
        return $this->_textColor;
    }
    
    /**
     * Récupérer la couleur Hexa du texte
     * @return string
     */
    public function getTextColorHexa()
    {
        return self::colorRGBToHexa($this->_textColor);
    }
    
    /**
     * Récupérer la couleur RGB du fond
     * @return array
     */
    public function getBgColorRGB()
    {
        return $this->_bgColor;
    }
    
    /**
     * Récupérer la couleur Hexa du fond
     * @return string
     */
    public function getBgColorHexa()
    {
        return self::colorRGBToHexa($this->_bgColor);
    }
    
    /**
     * Récupérer le nombre de ppp (ou dpi)
     * @return int
     */
    public function getDpi()
    {
        return $this->_dpi;
    } 
    
    /**
     * Récupérer la position en X
     * @return int
     */
    public function getPosX()
    {
        return $this->_posX;
    }
    
    /**
     * Récupérer la position en Y
     * @return int
     */
    public function getPosY()
    {
        return $this->_posY;
    }
    
    /**
     * Calcule le rectangle d'encadrement pour le texte, en utilisant la police courante
     * @return array
     * @access protected
     */
    protected function _getBBox()
    {
        if($this->_fontSize<=0 || !$this->checkFontFile())
            return false;
        
        return imageftbbox($this->_fontSize, 0, $this->_font, $this->_string);
    }
    
    /**
     * Permet de récupérer la position en x de façon littéral
     * @param  string  $posx  La position en x souhaité (left, center, right)
     * @return int|boolean
     */
    protected function _gePositionX($posx)
    {
        $bbox = $this->_getBBox();
        
        if(!$bbox)
            return false;
        
        switch(trim($posx))
        {
            case 'left':
                $x = 0;
                break;
                
            case 'center':
                $x = $bbox[0] + ($this->_width / 2) - ($bbox[2] / 2);
                break;
            
            case 'right' :
                $x = $this->_width-($bbox[2]-$bbox[0]);
                break;
            
            default:
                return false;
        }
        
        return $x;
    }
    
    /**
     * Permet de récupérer la position en y de façon littéral
     * @param  string  $posy  La position en y souhaité (top, middle, bottom)
     * @return int|boolean
     */
    protected function _gePositionY($posy)
    {
        $bbox = $this->_getBBox();
        
        if(!$bbox)
            return false;
        
        switch(trim($posy))
        {
            case 'top':
                $y = abs($bbox[7]);
                break;
                
            case 'middle':
                $y = $bbox[1] + ($this->_height / 2) - ($bbox[7] / 2);
                break;
            
            case 'bottom' :
                $y = $this->_height;
                break;
            
            default:
                return false;
        }
        
        return $y;
    }
    
    
  /****************/
  /***  TOOLS  ****/
  /****************/
    
    
    /**
     * Verifie que la couleur RGb est correct
     * @param  array  $colorRGB  Le tableau contenu les index des différente teine
     * @return boolean  vrai s'il correspond d'un couleur RGB correct, faux sinon.
     */
    public static function checkColorRGG($colorRGB)
    {
        if(!is_array($colorRGB))
            return false;
        
        if(count($colorRGB)!=3)
            return false;
        
        foreach($colorRGB as $color)
        {
            if($color<0 || $color>255)
                return false;
        }
        
        return true;
    }
    
    /**
     * Transforme une couleur hexadécimal en couleur RGB
     * @param  string  $colorHexa  La couleur hexadécimal (avec ou sans le #)
     * @return mixed  Le tableau de la couleur, faux la conversion à échoué.
     */
    public static function colorHexaToRGB($colorHexa)
    {
        $colorRGB = array();
        
        // gestion du #...
        if (substr($colorHexa,0,1)=="#") 
            $colorHexa=substr($colorHexa,1,6);

        $colorRGB[0] = hexdec(substr($colorHexa, 0, 2));
        $colorRGB[1] = hexdec(substr($colorHexa, 2, 2));
        $colorRGB[2] = hexdec(substr($colorHexa, 4, 2));
        
        return self::checkColorRGG($colorRGB) ? $colorRGB : false;
    }
    
    /**
     * Transforme une couleur RGB en couleur hexadécimal
     * @param  array  $colorRGB  La couleur RGB
     * @return mixed  Le code héxa de la couleur, faux si la conversion à échoué.
     */
    public static function colorRGBToHexa($colorRGB)
    {
        if(self::checkColorRGG($colorRGB))
            return "#" . str_pad(dechex( ($colorRGB[0]<<16)|($colorRGB[1]<<8)|$colorRGB[2] ), 6, "0", STR_PAD_LEFT);
        else
            return false;
    }
    
    /**
     * Convertir des cm en pixel
     * @param  float  $cm   Le nombre de cm
     * @param  $dpi   $dpi  Le nombre de ppp
     * @return int
     */
    public static function convertCmInPx($cm, $dpi=72)
    {
        return round(($cm*$dpi)/2.54);
    }
    
    /**
     * Convertir des pixel en cm
     * @param  int   $px   Le nombre de px
     * @param  $dpi  $dpi  Le nombre de ppp
     * @return flat
     */
    public static function convertPxInCm($px, $dpi=72, $float=2)
    {
        return floatval(round(($px/$dpi)*2.54, $float));
    }
    
    /**
     * Calcule le nombre de pixel en changant de ppp
     * @param  int  $px          Le nombre de px
     * @param  int  $dpi_origin  Le nombre de ppp d'origine
     * @param  int  $dpi_final   Le nombre de ppp pour le calcul
     * @return int
     */
    public static function changeDPI($px, $dpi_origin, $dpi_final=72)
    {
        return round(($px*$dpi_origin)/$dpi_final);
    }
    
    /**
     * Permet de vérifier si le fichier de la police est correct
     * @return boolean
     */
    public function checkFontFile()
    {
        return is_file($this->_font);
    }
    
    /**
	 * Génére un rapport d'erreur et retourne la valeur false.
	 * @param  string $error   L'erreur à retourner
	 * @param  string $method  Une chaine contenant la classe et la méthode responsables de l'erreur ("Classe::Méthode")
	 * @param  int    $line    La ligne où l'erreur a été provoquée
	 * @access protected
	 * @return bolean          Le booléen false
	 */
	protected function _reportError($method = __METHOD__, $line = __LINE__, $error = null)
    {
        throw new Exception('['.$method.']{'.$line.'} '.trim($error));
        return false;
    }
}

Initial URL


Initial Description
Create a simple image with text

Initial Title
Genrator Image Text

Initial Tags


Initial Language
PHP