BxDolImageResize.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  4. * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  5. *
  6. * @defgroup TridentCore Trident Core
  7. * @{
  8. */
  9. spl_autoload_register(function ($sClass) {
  10. // autoload Intervention Image files
  11. $sClass = trim($sClass, '\\');
  12. if (0 == strncmp('Intervention', $sClass, 12)) {
  13. $sFile = BX_DIRECTORY_PATH_PLUGINS . 'intervention-image/' . str_replace('\\', '/', $sClass) . '.php';
  14. if (file_exists($sFile))
  15. require_once($sFile);
  16. }
  17. });
  18. define('IMAGE_ERROR_SUCCESS', 0); ///< operation was successfull
  19. define('IMAGE_ERROR_WRONG_TYPE', 2); ///< operation failed, most probably because incorrect image format(or not image file) was provided
  20. class BxDolImageResize extends BxDol implements iBxDolSingleton
  21. {
  22. protected $w = 64, $h = 64; ///< size of destination image
  23. protected $_isAutoCrop = false;
  24. protected $_iJpegQuality = 90; ///< jpeg quality
  25. protected $_isSquareResize = false; ///< use smart resize, destination image will be exact Width x Height size
  26. protected $_isUseGD; ///< use GD library or command line ImagMagic utilites
  27. protected $_oManager; ///< Intervention Image Manager
  28. protected $_sError; ///< Intervention Image Manager error string
  29. function __construct()
  30. {
  31. if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
  32. trigger_error ('Multiple instances are not allowed for the class: ' . get_class($this), E_USER_ERROR);
  33. parent::__construct();
  34. $this->_isUseGD = getParam('enable_gd') == 'on' && extension_loaded('gd') ? true : false;
  35. $this->_oManager = new Intervention\Image\ImageManager(array('driver' => $this->_isUseGD ? 'gd' : 'imagick'));
  36. }
  37. /**
  38. * Prevent cloning the instance
  39. */
  40. public function __clone()
  41. {
  42. if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
  43. trigger_error('Clone is not allowed for the class: ' . get_class($this), E_USER_ERROR);
  44. }
  45. /**
  46. * Get singleton instance of the class
  47. */
  48. public static function getInstance()
  49. {
  50. if(!isset($GLOBALS['bxDolClasses'][__CLASS__]))
  51. $GLOBALS['bxDolClasses'][__CLASS__] = new BxDolImageResize();
  52. return $GLOBALS['bxDolClasses'][__CLASS__];
  53. }
  54. function getManager ()
  55. {
  56. return $this->_oManager;
  57. }
  58. function getError ()
  59. {
  60. return $this->_sError;
  61. }
  62. function isAllowedImage ($sSrcImage)
  63. {
  64. try {
  65. $this->_oManager->make($sSrcImage);
  66. }
  67. catch (Exception $e) {
  68. return false;
  69. }
  70. return true;
  71. }
  72. function resize ($mixedImage, $sDstImage = '')
  73. {
  74. if (is_array($mixedImage)) {
  75. $aRet = array();
  76. foreach ($mixedImage as $s) {
  77. $aRet[] = $this->_resize ($s, $s);
  78. }
  79. return $aRet;
  80. } else {
  81. return $this->_resize ($mixedImage, $sDstImage);
  82. }
  83. }
  84. function applyWatermark ($mixedImage, $sDstImage, $sWtrImage, $iTransparency, $sPosition = 'bottom-right', $sPositionOffsetX = 0, $sPositionOffsetY = 0, $sScaleFactor = 0.2 )
  85. {
  86. if (is_array($mixedImage)) {
  87. $aRet = array();
  88. foreach ($mixedImage as $s)
  89. $aRet[] = $this->_applyWatermark ($s, $s, $sWtrImage, $iTransparency, $sPosition, $sPositionOffsetX, $sPositionOffsetY, $sScaleFactor);
  90. return $aRet;
  91. } else {
  92. return $this->_applyWatermark ($mixedImage, $sDstImage, $sWtrImage, $iTransparency, $sPosition, $sPositionOffsetX, $sPositionOffsetY, $sScaleFactor);
  93. }
  94. }
  95. function grayscale ($mixedImage, $sDstImage = '')
  96. {
  97. if (is_array($mixedImage)) {
  98. $aRet = array();
  99. foreach ($mixedImage as $s) {
  100. $aRet[] = $this->_grayscale ($s, $s);
  101. }
  102. return $aRet;
  103. } else {
  104. return $this->_grayscale ($mixedImage, $sDstImage);
  105. }
  106. }
  107. function setSize ($w, $h)
  108. {
  109. $this->w = $w;
  110. $this->h = $h;
  111. }
  112. function removeCropOptions ()
  113. {
  114. $this->_isAutoCrop = false;
  115. }
  116. /**
  117. * Crop image to destination size with filling whole area of destination size
  118. */
  119. function setAutoCrop ($b)
  120. {
  121. $this->_isAutoCrop = $b;
  122. }
  123. function setJpegQuality ($i)
  124. {
  125. $this->_iJpegQuality = $i;
  126. }
  127. function setSquareResize ($b)
  128. {
  129. $this->_isSquareResize = ($b ? true : false);
  130. }
  131. function isUsedGD ()
  132. {
  133. return $this->_isUseGD;
  134. }
  135. static function getImageSize($sPath)
  136. {
  137. $o = self::getInstance();
  138. return $o->_getImageSize($sPath);
  139. }
  140. function _getImageSize($sPath)
  141. {
  142. $this->_sError = '';
  143. try {
  144. $o = $this->_oManager->make($sPath);
  145. }
  146. catch (Exception $e) {
  147. $this->_sError = $e->getMessage();
  148. return false;
  149. }
  150. return array ('w' => $o->width(), 'h' => $o->height());
  151. }
  152. function getExifInfo($sSrcImage, $bCreateLocalFileIfUrl = true)
  153. {
  154. $this->_sError = '';
  155. $sTmpFileName = false;
  156. $mixedRet = false;
  157. if ($bCreateLocalFileIfUrl && preg_match('/^https?:\/\//', $sSrcImage)) {
  158. $sTmpFileName = tempnam(BX_DIRECTORY_PATH_TMP, '');
  159. file_put_contents($sTmpFileName, file_get_contents($sSrcImage));
  160. }
  161. try {
  162. $mixedRet = $this->_oManager
  163. ->make($sTmpFileName ? $sTmpFileName : $sSrcImage)
  164. ->exif();
  165. }
  166. catch (Exception $e) {
  167. $this->_sError = $e->getMessage();
  168. }
  169. if ($sTmpFileName)
  170. @unlink($sTmpFileName);
  171. return $mixedRet;
  172. }
  173. function getAverageColor($sSrcImage)
  174. {
  175. $this->_sError = '';
  176. try {
  177. $a = $this->_oManager
  178. ->make($sSrcImage)
  179. ->resize(1, 1)
  180. ->pickColor(0, 0, 'array');
  181. return array('r' => $a[0], 'g' => $a[1], 'b' => $a[2]);
  182. }
  183. catch (Exception $e) {
  184. $this->_sError = $e->getMessage();
  185. return false;
  186. }
  187. }
  188. // private functions are below -------------------------------
  189. function _grayscale ($sSrcImage, $sDstImage = '')
  190. {
  191. $this->_sError = '';
  192. try {
  193. $this->_oManager
  194. ->make($sSrcImage)
  195. ->greyscale()
  196. ->save($sDstImage ? $sDstImage : $sSrcImage, $this->_iJpegQuality);
  197. chmod($sDstImage ? $sDstImage : $sSrcImage, BX_DOL_FILE_RIGHTS);
  198. }
  199. catch (Exception $e) {
  200. $this->_sError = $e->getMessage();
  201. return IMAGE_ERROR_WRONG_TYPE;
  202. }
  203. return IMAGE_ERROR_SUCCESS;
  204. }
  205. function _resize ($sSrcImage, $sDstImage = '')
  206. {
  207. $this->_sError = '';
  208. try {
  209. if ($this->_isAutoCrop || $this->_isSquareResize) {
  210. $this->_oManager
  211. ->make($sSrcImage)
  212. ->orientate()
  213. ->fit($this->w, $this->_isSquareResize ? $this->w : $this->h)
  214. ->save($sDstImage ? $sDstImage : $sSrcImage, $this->_iJpegQuality);
  215. }
  216. else {
  217. $this->_oManager
  218. ->make($sSrcImage)
  219. ->orientate()
  220. ->resize($this->w, $this->h, function ($constraint) {
  221. $constraint->aspectRatio();
  222. })
  223. ->save($sDstImage ? $sDstImage : $sSrcImage, $this->_iJpegQuality);
  224. }
  225. chmod($sDstImage ? $sDstImage : $sSrcImage, BX_DOL_FILE_RIGHTS);
  226. }
  227. catch (Exception $e) {
  228. $this->_sError = $e->getMessage();
  229. return IMAGE_ERROR_WRONG_TYPE;
  230. }
  231. return IMAGE_ERROR_SUCCESS;
  232. }
  233. function _applyWatermark( $sSrcImage, $sDstImage, $sWtrImage, $iTransparency, $sPosition = 'bottom-right', $sPositionOffsetX = 0, $sPositionOffsetY = 0, $sScaleFactor = 0.2)
  234. {
  235. $this->_sError = '';
  236. try {
  237. $oImageOrig = $this->_oManager->make($sSrcImage);
  238. $oImageOrig
  239. ->insert($this->_oManager
  240. ->make($sWtrImage)
  241. ->resize(round($oImageOrig->width() * $sScaleFactor), round($oImageOrig->height() * $sScaleFactor), function ($constraint) {
  242. $constraint->aspectRatio();
  243. $constraint->upsize();
  244. })
  245. ->opacity($iTransparency),
  246. $sPosition, $sPositionOffsetX, $sPositionOffsetY)
  247. ->save($sDstImage ? $sDstImage : $sSrcImage, $this->_iJpegQuality);
  248. chmod($sDstImage ? $sDstImage : $sSrcImage, BX_DOL_FILE_RIGHTS);
  249. }
  250. catch (Exception $e) {
  251. $this->_sError = $e->getMessage();
  252. return IMAGE_ERROR_WRONG_TYPE;
  253. }
  254. return IMAGE_ERROR_SUCCESS;
  255. }
  256. }
  257. /** @} */