PageRenderTime 58ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/core/media/image.class.php

https://github.com/konfirm/konsolidate
PHP | 442 lines | 205 code | 45 blank | 192 comment | 49 complexity | 8a90466ce1e544f90f088b38b0b779b3 MD5 | raw file
  1. <?php
  2. /*
  3. * ________ ___
  4. * / / /\ /\ Konsolidate
  5. * ____/ /___/ \/ \
  6. * / /\ / http://www.konsolidate.nl
  7. * /___ ___/ \ /
  8. * \ / /\ \ / \ Class: CoreMediaImage
  9. * \/___/ \___\/ \ Tier: Core
  10. * \ \ /\ \ /\ / Module: Media/Image
  11. * \___\/ \___\/ \/
  12. * \ \ / $Rev$
  13. * \___ ___\/ $Author$
  14. * \ \ / $Date$
  15. * \___\/
  16. */
  17. /**
  18. * Creation and manipulation of Images
  19. * @name CoreMediaImage
  20. * @type class
  21. * @package Konsolidate
  22. * @author Rogier Spieker <rogier@konsolidate.nl>
  23. */
  24. class CoreMediaImage extends Konsolidate
  25. {
  26. /**
  27. * The image resource
  28. * @name _image
  29. * @type resrouce
  30. * @access protected
  31. */
  32. protected $_image;
  33. /**
  34. * CoreImage constructor
  35. * @name CoreImage
  36. * @type constructor
  37. * @access public
  38. * @param object parent object
  39. * @return object
  40. * @syntax object = &new CoreImage( object parent )
  41. * @note This object is constructed by one of Konsolidates modules
  42. */
  43. public function __construct( &$oParent )
  44. {
  45. parent::__construct( $oParent );
  46. $this->_image = null;
  47. }
  48. /**
  49. * Create a new image (including an internal reference to it)
  50. * @name create
  51. * @type method
  52. * @access public
  53. * @param int width
  54. * @param int height
  55. * @param string hex backgroundcolor [optional]
  56. * @return resource image
  57. * @syntax Object->create( int width, int height [, string backgroundcolor ] );
  58. */
  59. public function create( $nWidth, $nHeight, $sBGColor=null )
  60. {
  61. $this->_image = $this->_create( $nWidth, $nHeight, $sBGColor );
  62. return $this->_image;
  63. }
  64. /**
  65. * Load an existing image (create an internal reference to it)
  66. * @name load
  67. * @type method
  68. * @access public
  69. * @param string filename
  70. * @return resource image
  71. * @syntax Object->load(string filename );
  72. */
  73. public function load( $sFile )
  74. {
  75. $this->_image = $this->_load( $sFile );
  76. return $this->_image;
  77. }
  78. /**
  79. * Merge two images into eachother
  80. * @name merge
  81. * @type method
  82. * @access public
  83. * @param mixed destination (string filename or image resource)
  84. * @param mixed source (string filename or image resource)
  85. * @param int X position in destination [optional]
  86. * @param int Y position in destination [optional]
  87. * @param int X position in source [optional]
  88. * @param int Y position in source [optional]
  89. * @param int width of the part to merge [optional]
  90. * @param int height of the part to merge [optional]
  91. * @param int percentage of transparency of the source region [optional]
  92. * @return resource image
  93. * @syntax Object->merge( mixed destination, mixed source [, int destX [, int destY [, int srcX [, int srcY [, int srcWidth [, int srcHeight [, int transparency ] ] ] ] ] ] ] );
  94. */
  95. public function merge( $mDestination, $mSource, $nDX=0, $nDY=0, $nSX=0, $nSY=0, $nSW=0, $nSH=0, $nPercentage=100 )
  96. {
  97. if ( !is_resource( $mSource ) )
  98. $mSource = $this->_load( $mSource );
  99. if ( !is_resource( $mDestination ) )
  100. $this->load( $mDestination );
  101. if ( $nSW <= 0 )
  102. $nSW = imagesx( $mSource ) - $nSX;
  103. if ( $nSH <= 0 )
  104. $nSH = imagesy( $mSource ) - $nSY;
  105. imagecopyresampled( $this->_image, $mSource, $nDX, $nDY, $nSX, $nSY, $nSW, $nSH, $nSW, $nSH );
  106. return $this->_image;
  107. }
  108. /**
  109. * Copy two images into eachother
  110. * @name copy
  111. * @type method
  112. * @access public
  113. * @param mixed destination (string filename or image resource)
  114. * @param mixed source (string filename or image resource)
  115. * @param int X position in destination [optional]
  116. * @param int Y position in destination [optional]
  117. * @param int X position in source [optional]
  118. * @param int Y position in source [optional]
  119. * @param int width of the part to image [optional]
  120. * @param int height of the part to merge [optional]
  121. * @return resource image
  122. * @syntax Object->copy( mixed destination, mixed source [, int destX [, int destY [, int srcX [, int srcY [, int srcWidth [, int srcHeight ] ] ] ] ] ] );
  123. */
  124. public function copy( $mDestination, $mSource, $nDX=0, $nDY=0, $nSX=0, $nSY=0, $nSW=0, $nSH=0 )
  125. {
  126. if ( !is_resource( $mDestination ) )
  127. $this->load( $mDestination );
  128. if ( !is_resource( $mSource ) )
  129. $mSource = $this->_load( $mSource );
  130. if ( $nSW <= 0 )
  131. $nSW = imagesx( $mSource ) - $nSX;
  132. if ( $nSH <= 0 )
  133. $nSH = imagesy( $mSource ) - $nSY;
  134. if ( imageistruecolor( $this->_image ) && imageistruecolor( $mSource ) )
  135. imagecopymerge( $this->_image, $mSource, $nDX, $nDY, $nSX, $nSY, $nSW, $nSH, 100 );
  136. else
  137. imagecopy( $this->_image, $mSource, $nDX, $nDY, $nSX, $nSY, $nSW, $nSH );
  138. return $this->_image;
  139. }
  140. /**
  141. * Resize an image
  142. * @name resize
  143. * @type method
  144. * @access public
  145. * @param mixed image (string filename or image resource)
  146. * @param int new width [optional]
  147. * @param int new height [optional]
  148. * @return resource image
  149. * @syntax Object->resize( mixed image [, int width [, int height ] ] );
  150. */
  151. public function resize( $mImage, $nWidth=0, $nHeight=0 )
  152. {
  153. if ( !is_resource( $mImage ) )
  154. $mImage = $this->load( $mImage );
  155. if ( $nWidth == 0 )
  156. $nWidth = imagesx( $mImage );
  157. if ( $nHeight == 0 )
  158. $nHeight = imagesy( $mImage );
  159. $this->create( $nWidth, $nHeight );
  160. imagecopyresampled( $this->_image, $mImage, 0, 0, 0, 0, $nWidth, $nHeight, imagesx( $mImage ), imagesy( $mImage ) );
  161. return $this->_image;
  162. }
  163. /**
  164. * Crop an image
  165. * @name crop
  166. * @type method
  167. * @access public
  168. * @param mixed image (string filename or image resource)
  169. * @param int X offset
  170. * @param int Y offset
  171. * @param int new width
  172. * @param int new height
  173. * @return resource image
  174. * @syntax Object->crop( mixed image, int offsetX, int offsetY, int width, int height );
  175. */
  176. public function crop( $mImage, $nX, $nY, $nWidth, $nHeight )
  177. {
  178. if ( !is_resource( $mImage ) )
  179. $mImage = $this->load( $mImage );
  180. if ( $nX < 0 )
  181. $nX = imagesx( $mImage ) - abs( $nX );
  182. if ( $nY < 0 )
  183. $nY = imagesy( $mImage ) - abs( $nY );
  184. if ( $nWidth < 0 )
  185. $nWidth = imagesx( $mImage ) - ( abs( $nWidth ) + $nX );
  186. if ( $nHeight < 0 )
  187. $nHeight = imagesy( $mImage ) - ( abs( $nHeight ) + $nY );
  188. $this->create( $nWidth, $nHeight );
  189. imagecopyresampled( $this->_image, $mImage, 0, 0, $nX, $nY, $nWidth, $nHeight, $nWidth, $nHeight );
  190. return $this->_image;
  191. }
  192. /**
  193. * Display (save) the generated image
  194. * @name display
  195. * @type method
  196. * @access public
  197. * @param string imagetype (one of: jpg|jpeg|gif|png) [optional]
  198. * @param int quality [optional]
  199. * @param string filename [optional]
  200. * @return resource image
  201. * @syntax Object->display( [ string type [, int quality [, string filename ] ] ] );
  202. */
  203. public function display( $sType="JPEG", $nQuality=75, $sFile=null )
  204. {
  205. switch( strToUpper( $sType ) )
  206. {
  207. case "GIF":
  208. case IMAGETYPE_GIF:
  209. if ( is_null( $sFile ) && !headers_sent() )
  210. header( "Content-type: image/gif" );
  211. @imagegif( $this->_image, $sFile );
  212. break;
  213. case "PNG":
  214. case IMAGETYPE_PNG:
  215. if ( is_null( $sFile ) && !headers_sent() )
  216. header( "Content-type: image/png" );
  217. @imagepng( $this->_image, $sFile, round( ( 9 / 100 ) * $nQuality ) );
  218. break;
  219. default:
  220. if ( is_null( $sFile ) && !headers_sent() )
  221. header( "Content-type: image/jpeg" );
  222. @imagejpeg( $this->_image, $sFile, $nQuality );
  223. break;
  224. }
  225. imagedestroy( $this->_image );
  226. ini_restore( "memory_limit" );
  227. return false;
  228. }
  229. /**
  230. * Fill an image with one solid color
  231. * @name fill
  232. * @type method
  233. * @access public
  234. * @param mixed image (string filename or image resource)
  235. * @param string hex backgroundcolor
  236. * @return bool
  237. * @syntax Object->fill( mixed image, string hexcolor )
  238. */
  239. public function fill( $mImage, $sColor )
  240. {
  241. if ( !is_resource( $mImage ) )
  242. $mImage = &$this->load( $mImage );
  243. return imagefilledrectangle( $mImage, 0, 0, imagesx( $mImage ), imagesy( $mImage ), $this->getColor( $sColor, $mImage ) );
  244. }
  245. /**
  246. * Allocate a color
  247. * @name getColor
  248. * @type method
  249. * @access public
  250. * @param string hex backgroundcolor
  251. * @param resource image [optional]
  252. * @return int color
  253. * @syntax Object->getColor( string hexcolor [, resource image ] )
  254. */
  255. public function getColor( $sColor, $mImage=null )
  256. {
  257. if ( is_null( $mImage ) )
  258. $mImage = &$this->_image;
  259. if ( substr( $sColor, 0, 1 ) == "#" )
  260. $sColor = substr( $sColor, 1 );
  261. if ( strLen( $sColor ) == 3 )
  262. $sColor = "{$sColor{0}}{$sColor{0}}{$sColor{1}}{$sColor{1}}{$sColor{2}}{$sColor{2}}";
  263. $sColor = str_pad( $sColor, 6, "0", STR_PAD_RIGHT );
  264. $nDec = hexdec( $sColor );
  265. return imagecolorallocate( $mImage, 0xFF & ( $nDec >> 0x10 ), 0xFF & ( $nDec >> 0x8 ), 0xFF & $nDec );
  266. }
  267. /**
  268. * Calculate contrained dimensions
  269. * @name getScaleDimension
  270. * @type method
  271. * @access public
  272. * @param resource image
  273. * @param int width [optional, default 0]
  274. * @param int height [optional, default 0]
  275. * @return int array( "width"=>W, "height"=>H );
  276. * @syntax Object->getScaleDimension( resource image, int width, int height )
  277. * @note provide 0 for either the width or the height to obtain it's constrained counterpart, provide 0 for both to obtain the current dimensions
  278. */
  279. public function getScaleDimension( $mImage, $nWidth=0, $nHeight=0 )
  280. {
  281. // find out whether the programmer wants us to calculate either the width or the height
  282. if ( $nWidth <= 0 && $nHeight > 0 )
  283. {
  284. $nFactor = $nHeight / imagesy( $mImage );
  285. $nWidth = imagesx( $mImage ) * $nFactor;
  286. }
  287. else if ( $nWidth > 0 && $nHeight <= 0 )
  288. {
  289. $nFactor = $nWidth / imagesx( $mImage );
  290. $nHeight = imagesy( $mImage ) * $nFactor;
  291. }
  292. else
  293. {
  294. $nWidth = imagesx( $mImage );
  295. $nHeight = imagesy( $mImage );
  296. }
  297. return Array(
  298. "width"=>$nWidth,
  299. "height"=>$nHeight
  300. );
  301. }
  302. /**
  303. * Calculate and attempt to adjust the memory limit for specified size image
  304. * @name adjustMemoryUsage
  305. * @type method
  306. * @access public
  307. * @param int width
  308. * @param int height
  309. * @param int bits [optional]
  310. * @param int channels [optional]
  311. * @return bool
  312. * @syntax Object->adjustMemoryUsage( int width, int height [, int bits [, int channels ] ] )
  313. */
  314. public function adjustMemoryUsage( $nWidth, $nHeight, $nBits=8, $nChannels=4 )
  315. {
  316. $nBytes = ( $nWidth * $nHeight * $nBits * $nChannels ) / 8 + pow( 2, 16 ) * 2.2;
  317. if ( function_exists( "memory_get_usage" ) )
  318. {
  319. if ( memory_get_usage() + $nBytes > (int) ini_get( "memory_limit" ) * pow( 1024, 2 ) )
  320. return ini_set( "memory_limit", (int) ceil( ( memory_get_usage() + $nBytes ) / pow( 1024, 2 ) ) . "M" );
  321. return true;
  322. }
  323. return false;
  324. }
  325. /**
  326. * Create a new image
  327. * @name _create
  328. * @type method
  329. * @access protected
  330. * @param int width
  331. * @param int height
  332. * @param string hex backgroundcolor [optional]
  333. * @return resource image
  334. * @syntax Object->_create( int width, int height [, string backgroundcolor ] );
  335. */
  336. protected function _create( $nWidth, $nHeight, $sBGColor=null )
  337. {
  338. $this->adjustMemoryUsage( $nWidth, $nHeight );
  339. $oImage = null;
  340. if ( function_exists( "imagecreatetruecolor" ) )
  341. {
  342. $oImage = imagecreatetruecolor( $nWidth, $nHeight );
  343. $nTrans = imagecolorallocate( $oImage, 0, 0, 0 );
  344. imagesavealpha( $oImage, true );
  345. imagefill( $oImage, 0, 0, imagecolorallocatealpha( $oImage, 0, 0, 0, 127 ) );
  346. }
  347. else if ( function_exists( "imagecreate" ) )
  348. {
  349. $oImage = imagecreate( $nWidth, $nHeight );
  350. }
  351. if ( !is_null( $sBGColor ) && is_resource( $oImage ) )
  352. $this->fill( $oImage, $sBGColor );
  353. return $oImage;
  354. }
  355. /**
  356. * Load an existing image
  357. * @name _load
  358. * @type method
  359. * @access protected
  360. * @param string filename
  361. * @return resource image (bool false on error)
  362. * @syntax Object->_load( string filename );
  363. */
  364. protected function _load( $sFile )
  365. {
  366. $oImage = null;
  367. if ( file_exists( $sFile ) )
  368. {
  369. $aFile = getimagesize( $sFile );
  370. // if getimagesize wasn't able to do its deed, return false
  371. if ( $aFile === false )
  372. return false;
  373. $this->adjustMemoryUsage( $aFile[ 0 ], $aFile[ 1 ] );
  374. switch( $aFile[ 2 ] )
  375. {
  376. case IMAGETYPE_GIF:
  377. if ( function_exists( "imagecreatefromgif" ) )
  378. $oImage = imagecreatefromgif( $sFile );
  379. break;
  380. case IMAGETYPE_PNG:
  381. if ( function_exists( "imagecreatefrompng" ) )
  382. {
  383. $oImage = imagecreatefrompng( $sFile );
  384. imagealphablending( $oImage, true );
  385. imagesavealpha( $oImage, true );
  386. }
  387. break;
  388. case IMAGETYPE_JPEG:
  389. if ( function_exists( "imagecreatefromjpeg" ) )
  390. $oImage = imagecreatefromjpeg( $sFile );
  391. break;
  392. }
  393. }
  394. return $oImage;
  395. }
  396. }
  397. ?>