Last active
July 9, 2017 13:48
-
-
Save maximishchenko/43a84e23b3414c223b596ed612c69a16 to your computer and use it in GitHub Desktop.
PHP Fill or Fit Image (based on gd library)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace common\widgets; | |
/** | |
* Crop fill or fit image with php-gd library | |
* @author Maxim Ishchenko <maxim.ishchenko@gmail.com> | |
* @version 1.0* | |
* @uses, @example | |
* @license GPL | |
* @license http://opensource.org/licenses/gpl-license.php GNU Public License | |
* | |
* $image = new ImageFill( | |
* array( | |
* 'source' => 'source.jpg', // required source image | |
* 'h' => 250, // optional, if missing uses ImageFill::DEFAULT_HEIGHT value | |
* 'w' => 250, // optional, if missing uses ImageFill::DEFAULT_WIDTH value | |
* 'mode' => 'fill', // optional, must be 'fit' or 'fill', default 'fill' | |
* 'saveFile' => false, // optional, is need to save file, default - true, must be boolean, file be saved into ImageFill::DESTINATION_PATH | |
* ) | |
* ); | |
* | |
* @property string $source | |
* @property integer $h | |
* @property integer $w | |
* @property string $mode | |
* @property bool $saveFile | |
*/ | |
class ImageFill | |
{ | |
/** | |
* @constant MIN_HEIGHT minimal image height | |
* @constant MIN_WIDTH minimal image width | |
* @constant MAX_HEIGHT maximum available image height | |
* @constant MAX_WIDTH maximum available image width | |
* @constant DEFAULT_WIDTH standart image width | |
* @constant DEFAULT_HEIGHT standart image height | |
* @constant DEFAULT_MODE standart mode (if not set in $args array) | |
* @constant DESTINATION_PATH path to save output images (if $saveFile argument is true) | |
*/ | |
const MIN_HEIGHT = 1; | |
const MIN_WIDTH = 1; | |
const MAX_HEIGHT = 1000; | |
const MAX_WIDTH = 1000; | |
const DEFAULT_HEIGHT = 100; | |
const DEFAULT_WIDTH = 100; | |
const DEFAULT_MODE = 'fill'; | |
const DESTINATION_PATH = 'images/output.jpg'; | |
/** | |
* @access private | |
* @property integer $h | |
* @property integer $w | |
* @property bool $saveFile | |
* @property string $mode | |
* @property string $source | |
* @property array $availableModes | |
*/ | |
private $h; | |
private $w; | |
private $saveFile; | |
private $mode; | |
private $source; | |
private $availableModes = array('fit', 'fill'); | |
function __construct($args = array()) | |
{ | |
/** | |
* source required | |
* @property string $source | |
* @access private | |
* @return Exception if not set or image resourse if variable is set | |
*/ | |
if(!isset($args['source'])) { | |
throw new Exception("FillImage. One or more required parameters are missing!", 1); | |
} else { | |
/** | |
* @link http://php.net/manual/ru/function.imagecreatefromjpeg.php | |
*/ | |
$this->source = imagecreatefromjpeg($args['source']); | |
} | |
/** | |
* Set default source value to DEFAULT_MODE constant if $mode is not set | |
* Check if mode is in range (fit, fill) | |
* @constant DEFAULT_MODE | |
* @property string $mode | |
* @access private | |
* @return Exception if not in range from $availableModes array, else return pre-defined value | |
*/ | |
if(isset($args['mode']) && !in_array($args['mode'], $this->availableModes)) { | |
throw new Exception("FillImage. Incorrect mode!", 1); | |
} else { | |
$this->mode = (isset($args['mode']) && $args['mode'] == 'fit') ? 'fit' : self::DEFAULT_MODE; | |
} | |
/** | |
* Check if isset $saveFile, is $saveFile is boolean and set it to true if not set | |
* @property bool $saveFile | |
* @access private | |
* @return true | false | |
*/ | |
if($args['saveFile'] !== null && !is_bool($args['saveFile'])) { | |
throw new Exception("Incorrect saveFile value", 1); | |
} elseif($args['saveFile'] !== null && is_bool($args['saveFile'])) { | |
$this->saveFile = $args['saveFile']; | |
} else { | |
$this->saveFile = true; | |
} | |
/** | |
* Check if isset $h value. If not set it to DEFAULT_HEIGHT | |
* Alse check if $h value in range (MIN_HEIGHT, MAX_HEIGHT), if not - set to DEFAULT_HEIGHT | |
* @constant MIN_HEIGHT | |
* @constant MIN_WIDTH | |
* @constant MAX_HEIGHT | |
* @constant MAX_WIDTH | |
* @property integer $h | |
* @access private | |
* @return integer $h value from $args array if it set or set $h to DEFAULT_HEIGHT value | |
*/ | |
if(isset($args['h'])) { | |
/** | |
* @link http://php.net/manual/ru/function.intval.php | |
*/ | |
$this->h = intval($args['h']); | |
$this->h = ($this->h <= self::MIN_HEIGHT || $this->h >= self::MAX_HEIGHT) ? self::DEFAULT_HEIGHT : $this->h; | |
} else { | |
$this->h = self::DEFAULT_HEIGHT; | |
} | |
/** | |
* Check if isset $w value. If not set it to DEFAULT_HEIGHT | |
* Alse check if $w value in range (MIN_HEIGHT, MAX_HEIGHT), if not - set to DEFAULT_HEIGHT | |
* @constant MIN_WIDTH | |
* @constant MAX_WIDTH | |
* @constant DEFAULT_WIDTH | |
* @property integer $w | |
* @access private | |
* @return integer $w value from $args array if it set or set $w to DEFAULT_HEIGHT value | |
*/ | |
if(isset($args['w'])) { | |
/** | |
* @link http://php.net/manual/ru/function.intval.php | |
*/ | |
$this->w = intval($args['w']); | |
$this->w = ($this->w <= self::MIN_WIDTH || $this->w >= self::MAX_WIDTH) ? self::DEFAULT_WIDTH : $this->w; | |
} else { | |
$this->w = self::DEFAULT_WIDTH; | |
} | |
/** | |
* Run result function to get croped-image | |
* @see getDestinationImage() | |
*/ | |
$this->getDestinationImage(); | |
} | |
/** | |
* @access private | |
* @constant DEFAULT_MODE | |
* @property string $source | |
* @param string $dst_image | |
* @var integer $new_width | |
* @var integer $new_height | |
* @var integer $new_x | |
* @var integer $new_y | |
* @var integer $next | |
* @var integer $dst_width | |
* @var integer $src_height | |
* @var integer $src_width | |
* @var integer $dst_height | |
* @var string $dst_image | |
*/ | |
private function scaleImage($dst_image) | |
{ | |
/** | |
* Get source image width | |
* @link http://php.net/manual/ru/function.imagesx.php | |
*/ | |
$src_width = imagesx($this->source); | |
/** | |
* Get source image height | |
* @link http://php.net/manual/ru/function.imagesy.php | |
*/ | |
$src_height = imagesy($this->source); | |
/** | |
* Get destination image width | |
* @link http://php.net/manual/ru/function.imagesx.php | |
*/ | |
$dst_width = imagesx($dst_image); | |
/** | |
* Get destination image height | |
*/ | |
$dst_height = imagesy($dst_image); | |
/** | |
* Try to match destination image by width | |
* @link http://php.net/manual/ru/function.imagesy.php | |
*/ | |
$new_width = $dst_width; | |
$new_height = round($new_width*($src_height/$src_width)); | |
$new_x = 0; | |
/** | |
* @link http://php.net/manual/ru/function.round.php | |
*/ | |
$new_y = round(($dst_height-$new_height)/2); | |
$next = $this->mode == self::DEFAULT_MODE ? $new_height < $dst_height : $new_height > $dst_height; | |
/** | |
* If match by width failed and destination image does not fit, try by height | |
*/ | |
if ($next) { | |
$new_height = $dst_height; | |
/** | |
* @link http://php.net/manual/ru/function.round.php | |
*/ | |
$new_width = round($new_height*($src_width/$src_height)); | |
$new_x = round(($dst_width - $new_width)/2); | |
$new_y = 0; | |
} | |
/** | |
* Copy image on right place | |
* @link http://php.net/manual/ru/function.imagecopyresampled.php | |
*/ | |
imagecopyresampled($dst_image, $this->source , $new_x, $new_y, 0, 0, $new_width, $new_height, $src_width, $src_height); | |
} | |
/** | |
* Return destination image to browser or save it to file | |
* @access private | |
* @property integer $w | |
* @property integer $h | |
* @property bool $saveFile | |
* @param string $dst | |
*/ | |
private function getDestinationImage() | |
{ | |
/** | |
* @link http://php.net/manual/ru/function.imagecreatetruecolor.php | |
*/ | |
$dst = imagecreatetruecolor($this->w, $this->h); | |
/** | |
* @link http://php.net/manual/ru/function.imagefill.php | |
*/ | |
imagefill($dst, 0, 0, imagecolorallocate($dst, 255, 255, 255)); | |
/** | |
* @see $scaleImage | |
*/ | |
$this->scaleImage($dst); | |
/** | |
* Output to the browser | |
* @link http://php.net/manual/ru/function.imagejpeg.php | |
*/ | |
imagejpeg($dst, ($this->saveFile) ? self::DESTINATION_PATH : null); | |
} | |
} | |
// Header('Content-Type: image/jpeg'); | |
/** | |
* @see ImageFill() | |
*/ | |
// $image = new ImageFill( | |
// array( | |
// 'h' => 250, | |
// 'w' => 250, | |
// 'source' => 'source.jpg', | |
// 'mode' => 'fill', | |
// 'saveFile' => false, | |
// ) | |
// ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment