Source for file Image.class.php

Documentation is available at Image.class.php

  1. /**
  2.  * Класс Image.
  3.  *
  4.  * @package energine
  5.  * @author 1m.dm
  6.  * @copyright ColoCall 2006
  7.  * @version $Id: fsource_energine__modulesimagecomponentsImage.class.php.html,v 1.1 2007/09/17 14:32:30 pavka Exp $
  8.  */
  9.  
  10. require_once 'core/framework/Object.class.php';
  11. require_once 'core/framework/SystemException.class.php';
  12.  
  13. /**
  14.  * Класс для работы с изображениями.
  15.  *
  16.  * @package energine
  17.  * @subpackage image
  18.  */
  19. class Image extends Object {
  20.  
  21.     /**
  22.      * Количество памяти по умолчанию(если cкомпилировано без memory-limit)
  23.      * 16M
  24.      *
  25.      */
  26.     const DEFAULT_MEMORY_LIMIT = 16777216;
  27.  
  28.     /**
  29.      * Тип изображения:
  30.      */
  31.     /**
  32.      * Неизвестный
  33.      */
  34.     const TYPE_UNKNOWN = 0;
  35.     /**
  36.      * Portable Network Graphics
  37.      */
  38.     const TYPE_PNG     = 1;
  39.     /**
  40.      * Graphics Interchange Format
  41.      */
  42.     const TYPE_GIF     = 2;
  43.     /**
  44.      * Joint Photographic Experts Group
  45.      */
  46.     const TYPE_JPEG    = 3;
  47.  
  48.     ////////////////////////////////////////////////////////////////////////////
  49.  
  50.     /**
  51.      * Сопоставление расширений файлов типам.
  52.      *
  53.      * @access private
  54.      * @var array 
  55.      */
  56.     private $extensions = array(
  57.         'png'  => self::TYPE_PNG,
  58.         'gif'  => self::TYPE_GIF,
  59.         'jpg'  => self::TYPE_JPEG,
  60.         'jpe'  => self::TYPE_JPEG,
  61.         'jpeg' => self::TYPE_JPEG
  62.     );
  63.  
  64.     ////////////////////////////////////////////////////////////////////////////
  65.  
  66.     /**
  67.      * Изображение.
  68.      *
  69.      * @access private
  70.      * @var resource 
  71.      */
  72.     private $image;
  73.  
  74.     /**
  75.      * Ширина изображения.
  76.      *
  77.      * @access private
  78.      * @var int 
  79.      */
  80.     private $width;
  81.  
  82.     /**
  83.      * Высота изображения.
  84.      *
  85.      * @access private
  86.      * @var int 
  87.      */
  88.     private $height;
  89.  
  90.     /**
  91.      * Тип изображения (см. выше список типов).
  92.      *
  93.      * @access private
  94.      * @var int 
  95.      */
  96.     private $type;
  97.  
  98.     ////////////////////////////////////////////////////////////////////////////
  99.  
  100.     /**
  101.      * Конструктор класса.
  102.      *
  103.      * @access public
  104.      * @return void 
  105.      */
  106.     public function __construct({
  107.         parent::__construct();
  108.     }
  109.  
  110.     /**
  111.      * Создание изображения заданной ширины и высоты.
  112.      *
  113.      * @access public
  114.      * @param int $width - ширина
  115.      * @param int $height - высота
  116.      * @return void 
  117.      */
  118.     public function create($width$height{
  119.         if (!$this->checkAvailableMemory($width$height)) {
  120.             throw new SystemException('ERR_MEMORY_NOT_AVAILABLE'SystemException::ERR_NOTICE);
  121.         }
  122.  
  123.         $this->image  = imagecreatetruecolor($width$height);
  124.         $this->width  = $width;
  125.         $this->height = $height;
  126.         $this->type   = self::TYPE_UNKNOWN;
  127.     }
  128.  
  129.     ////////
  130.  
  131.     private function checkAvailableMemory($width$height{
  132.         $isMemoryAvailable true;
  133.         $memoryLimit $this->convertSizeToBytes(ini_get('memory_limit'));
  134.         $memoryNeeded $width $height 4/*B = 32BPP*/ 1.5// 1.5 - Хрен Его Знает Что За Фактор :)
  135.         if (function_exists('memory_get_usage')) {
  136.             /*
  137.              * если мы можем узнать занимаемую скриптом память,
  138.              * проверяем количество свободной памяти простым вичитанием
  139.              * занимаемой памяти из установленного лимита.
  140.              */
  141.             $memoryUsage = memory_get_usage();
  142.             $isMemoryAvailable $memoryNeeded ($memoryLimit $memoryUsage);
  143.         }
  144.  
  145.         return $isMemoryAvailable;
  146.     }
  147.  
  148.     private function convertSizeToBytes($size{
  149.         if (!empty($size)) {
  150.             $size = trim($size);
  151.             $measurement = strtolower($size[strlen($size)-1]);
  152.             switch($measurement{
  153.                 case 'g'$size *= 1024;
  154.                 case 'm'$size *= 1024;
  155.                 case 'k'$size *= 1024;
  156.             }
  157.         }
  158.         else {
  159.             $size self::DEFAULT_MEMORY_LIMIT;
  160.         }
  161.  
  162.         return $size;
  163.     }
  164.  
  165.     ////////
  166.  
  167.     public function getWidth({
  168.         return $this->width;
  169.     }
  170.  
  171.     public function getHeight({
  172.         return $this->height;
  173.     }
  174.  
  175.     /**
  176.      * Загружает изображение из файла.
  177.      * Если тип изображения явно не указан, метод попытается определить его
  178.      * самостоятельно, основываясь на расширении файла. В случае неудачи
  179.      * будет возбуждено исключение.
  180.      *
  181.      * @access public
  182.      * @param int $filename - имя файла
  183.      * @param int $type - тип изображения
  184.      * @return void 
  185.      */
  186.     public function loadFromFile($filename$type self::TYPE_UNKNOWN{
  187.         if (!file_exists($filename)) {
  188.             throw new SystemException('ERR_DEV_FILE_DOESNT_EXISTS'SystemException::ERR_DEVELOPER$filename);
  189.         }
  190.  
  191.         if ($type == self::TYPE_UNKNOWN{
  192.             // пробуем определить тип по расширению
  193.             $ext $this->getExtension($filename);
  194.             if (!array_key_exists($ext$this->extensions)) {
  195.                 throw new SystemException('ERR_CANNOT_DETERMINE_IMAGE_TYPE'SystemException::ERR_WARNING$filename);
  196.             }
  197.             $type $this->extensions[$ext];
  198.         }
  199.  
  200.         if (!$imageSize @getimagesize($filename)) {
  201.             throw new SystemException('ERR_BAD_FILE_FORMAT'SystemException::ERR_WARNING$filename);
  202.         }
  203.         if (!$this->checkAvailableMemory($imageSize[0]$imageSize[1])) {
  204.             throw new SystemException('ERR_MEMORY_NOT_AVAILABLE'SystemException::ERR_NOTICE);
  205.         }
  206.  
  207.         $image null;
  208.         switch ($type{
  209.             case self::TYPE_PNG:  $image = imagecreatefrompng($filename);  break;
  210.             case self::TYPE_GIF:  $image = imagecreatefromgif($filename);  break;
  211.             case self::TYPE_JPEG$image = imagecreatefromjpeg($filename)break;
  212.             default// unreachable
  213.         }
  214.  
  215.         if (!$image{
  216.             throw new SystemException('ERR_BAD_FILE_FORMAT'SystemException::ERR_WARNING$filename);
  217.         }
  218.  
  219.         $this->image  = $image;
  220.         $this->width  = imagesx($this->image);
  221.         $this->height = imagesy($this->image);
  222.         $this->type   = $type;
  223.     }
  224.  
  225.     /**
  226.      * Сохраняет изображение в файл.
  227.      * Если тип изображения явно не указан, метод попытается определить его
  228.      * самостоятельно, основываясь на расширении файла. В случае неудачи
  229.      * будет возбуждено исключение.
  230.      *
  231.      * @access public
  232.      * @param int $filename - имя файла
  233.      * @param int $type - тип изображения
  234.      * @return void 
  235.      */
  236.     public function saveToFile($filename$type self::TYPE_UNKNOWN{
  237.         if (!$this->image{
  238.             throw new SystemException('ERR_DEV_NO_IMAGE_TO_SAVE'SystemException::ERR_DEVELOPER$filename);
  239.         }
  240.  
  241.         if ($type == self::TYPE_UNKNOWN{
  242.             $ext $this->getExtension($filename);
  243.             if (array_key_exists($ext$this->extensions)) {
  244.                 $type $this->extensions[$ext];
  245.             }
  246.             elseif ($this->type != self::TYPE_UNKNOWN{
  247.                 $type $this->type;
  248.             }
  249.             else {
  250.                 throw new SystemException('ERR_CANNOT_DETERMINE_IMAGE_TYPE'SystemException::ERR_WARNING$filename);
  251.             }
  252.         }
  253.  
  254.         $success false;
  255.         switch ($type{
  256.             case self::TYPE_PNG:  $success @imagepng ($this->image$filename)break;
  257.             case self::TYPE_GIF:  $success @imagegif ($this->image$filename)break;
  258.             case self::TYPE_JPEG$success @imagejpeg($this->image$filename)break;
  259.             default// unreachable
  260.         }
  261.  
  262.         if (!$success{
  263.             throw new SystemException('ERR_CANT_SAVE_FILE'SystemException::ERR_WARNING$filename);
  264.         }
  265.         try {
  266.             @chmod($filename0777);
  267.         }
  268.         catch (Exception $e){}
  269.         return $success;
  270.     }
  271.  
  272.     /**
  273.      * Изменяет размер (разрешение) изображения.
  274.      * Если ширина ИЛИ высота равны null -- они вычисляются пропорционально.
  275.      *
  276.      * @access public
  277.      * @param mixed $newWidth - новая ширина
  278.      * @param mixed $newHeight - новая высота
  279.      * @param boolean $stretch - растягивать изображение на всю площадь "холста" (true),
  280.      *                            или вписывать соблюдая пропорции (false; по-умолчанию)
  281.      * @return void 
  282.      */
  283.     public function resize($newWidth$newHeight/*, $stretch = false*/{
  284.         if (!isset($newWidth&& !isset($newHeight)) {
  285.             throw new SystemException('ERR_DEV_BAD_SIZE'SystemException::ERR_DEVELOPER);
  286.         }
  287.  
  288.         $aspectRatio $this->width / $this->height;
  289.         $newCanvasWidth $newWidth;
  290.         $newCanvasHeight $newHeight;
  291.         $posX $posY 0;
  292.  
  293.         if (!isset($newWidth)) {
  294.             $newWidth $newHeight $aspectRatio;
  295.             $newCanvasWidth $newWidth;
  296.         }
  297.         elseif (!isset($newHeight)) {
  298.             $newHeight $newWidth $aspectRatio;
  299.             $newCanvasHeight $newHeight;
  300.         }
  301.         /*
  302.         elseif ($stretch) {
  303.             // TODO: stretch!
  304.         }
  305.         */
  306.         else {
  307.             if ($newWidth $newHeight{
  308.                 $newWidth $newHeight $aspectRatio;
  309.                 $posX ($newCanvasWidth $newWidth2;
  310.                 $posY 0;
  311.             }
  312.             else {
  313.                 $newHeight $newWidth $aspectRatio;
  314.                 $posX 0;
  315.                 $posY ($newCanvasHeight $newHeight2;
  316.             }
  317.         }
  318.  
  319.         $newCanvasWidth = ceil($newCanvasWidth);
  320.         $newCanvasHeight = ceil($newCanvasHeight);
  321.  
  322.         if (!$this->checkAvailableMemory($newCanvasWidth$newCanvasHeight)) {
  323.             throw new SystemException('ERR_MEMORY_NOT_AVAILABLE'SystemException::ERR_NOTICE);
  324.         }
  325.  
  326.         $resizedImage = imagecreatetruecolor($newCanvasWidth$newCanvasHeight);
  327.         $bgColor = imagecolorallocate($resizedImage255255255);
  328.         imagefill($resizedImage00$bgColor);
  329.  
  330.         imagecopyresampled(
  331.             $resizedImage$this->image,
  332.             $posX$posY00,
  333.             ceil($newWidth)ceil($newHeight),
  334.             $this->width$this->height
  335.         );
  336.         imagedestroy($this->image);
  337.  
  338.         $this->image  = $resizedImage;
  339.         $this->width  = $newWidth;
  340.         $this->height = $newHeight;
  341.     }
  342.  
  343.     ////////////////////////////////////////////////////////////////////////////
  344.  
  345.     /**
  346.      * Возвращает расширение файла.
  347.      *
  348.      * @access private
  349.      * @param string $filename 
  350.      * @return string 
  351.      */
  352.     private function getExtension($filename{
  353.         return substr(strrchr($filename'.')1);
  354.     }
  355.  
  356.     public function __destruct({
  357.         if ($this->image{
  358.            imagedestroy($this->image);
  359.         }
  360.     }
  361. }

Documentation generated on Mon, 17 Sep 2007 13:30:02 +0300 by phpDocumentor 1.4.0a2