This time however I needed to find a good class Image that works with GD and is designed nicely. After 10 min of search I decided to write my own. So, for the lack of better place, I will put it here. If you are not into the obvious - skip this post.
<? /** * Class Image * @author Alexander Podgorny * @license GPL */ class Image { const RESIZE_FILL = 2; // When resizing, constrain proportions, keep largest dimension const RESIZE_FIT = 3; // When resizing, constrain proportions, keep smallest dimension const RESIZE_STRETCH = 1; // When resizing, do not constrain proportions, keep both dimensions const TYPE_JPEG = 10; const TYPE_GIF = 11; const TYPE_PNG = 12; private $_sFileName = ''; private $_oImage = null; private $_nW = 0; private $_nH = 0; public function __construct($sFileName=null) { if ($sFileName) { $this->open($sFileName); } } public function __destruct() { imagedestroy($this->_oImage); } public function open($sFileName) { if (!file_exists($sFileName)) { throw new Exception('File could not be found: '.$sFileName); } $this->_sFileName = $sFileName; $sExtension = strtolower(strrchr($sFileName, '.')); switch ($sExtension) { case '.jpg': case '.jpeg': $this->_oImage = imagecreatefromjpeg($sFileName); break; case '.gif': $this->_oImage = imagecreatefromgif($sFileName); break; case '.png': $this->_oImage = imagecreatefrompng($sFileName); break; default: throw new Exception('Unknown file type: '.$sFileName); } $this->_nW = imagesx($this->_oImage); $this->_nH = imagesy($this->_oImage); return $this; } public function resize($nW, $nH, $nOption=self::RESIZE_FIT) { $nSrcRatio = $this->_nW / $this->_nH; $nDstRatio = $nW / $nH; switch ($nOption) { case self::RESIZE_STRETCH: // do nothing; break; case self::RESIZE_FILL: if ($nDstRatio > $nSrcRatio) { $nH = $nW / $nSrcRatio; } else { $nW = $nSrcRatio * $nH; } break; case self::RESIZE_FIT: default: if ($nDstRatio > $nSrcRatio) { $nW = $nSrcRatio * $nH; } else { $nH = $nW / $nSrcRatio; } break; } $nW = floor($nW); $nH = floor($nH); $oImageResized = imagecreatetruecolor($nW, $nH); imagecopyresampled( $oImageResized, $this->_oImage, 0, 0, 0, 0, $nW, $nH, $this->_nW, $this->_nH ); imagedestroy($this->_oImage); $this->_oImage = $oImageResized; $this->_nW = $nW; $this->_nH = $nH; return $this; } public function save($sFileName=null, $nQuality=null) { if (!$sFileName) { $sFileName = $this->_sFileName; } $sExtension = strtolower(strrchr($sFileName, '.')); if (!$sFileName) { throw new Exception('Could not save file. File name is not supplied'); } switch ($sExtension) { case '.jpg': case '.jpeg': if ($nQuality !== null) { // otherwise use built in default if ($nQuality < 0) { $nQuality = 0; } if ($nQuality > 100) { $nQuality = 100; } } imagejpeg($this->_oImage, $sFileName, $nQuality); break; case '.gif': imagegif($this->_oImage, $sFileName); break; case '.png': if ($nQuality !== null) { // otherwise use built in default if ($nQuality > 9) { $nQuality = 9; } if ($nQuality < 0) { $nQuality = 0; } } imagepng($this->_oImage, $sFileName, $nQuality); break; default: throw new Exception('Unknown file type: '.$sFileName); break; } return $this; } public function output($nType=self::TYPE_JPEG, $nQuality=null) { switch ($nType) { case self::TYPE_JPEG: if ($nQuality) { // otherwise use built in default if ($nQuality < 0) { $nQuality = 0; } if ($nQuality > 100) { $nQuality = 100; } } header('Content-type: image/jpeg'); imagejpeg($this->_oImage, null, $nQuality); break; case self::TYPE_GIF: header('Content-type: image/gif'); imagegif($this->_oImage, null); break; case self::TYPE_PNG: if ($nQuality) { // otherwise use built in default if ($nQuality > 9) { $nQuality = 9; } if ($nQuality < 0) { $nQuality = 0; } } header('Content-type: image/png'); imagepng($this->_oImage, null, $nQuality); break; default: throw new Exception('Unknown file type'); break; } return $this; } } ?>