Image.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <?php
  2. namespace Grafika\Imagick;
  3. use Grafika\ImageInterface;
  4. use Grafika\ImageType;
  5. /**
  6. * Image class for Imagick.
  7. * @package Grafika\Gd
  8. */
  9. final class Image implements ImageInterface {
  10. /**
  11. * @var \Imagick Imagick instance
  12. */
  13. private $imagick;
  14. /**
  15. * @var string File path to image
  16. */
  17. private $imageFile;
  18. /**
  19. * @var int Image width in pixels
  20. */
  21. private $width;
  22. /**
  23. * @var int Image height in pixels
  24. */
  25. private $height;
  26. /**
  27. * @var string Image type. Return value of Imagick::queryFormats(). See http://phpimagick.com/Imagick/queryFormats
  28. * Sample values: JPEG, PNG, GIF, WBMP
  29. */
  30. private $type;
  31. /**
  32. * @var bool True if image is an animated GIF.
  33. */
  34. private $animated;
  35. /**
  36. * Image constructor.
  37. *
  38. * @param \Imagick $imagick
  39. * @param string $imageFile
  40. * @param int $width
  41. * @param int $height
  42. * @param string $type
  43. * @param bool $animated
  44. */
  45. public function __construct( \Imagick $imagick, $imageFile, $width, $height, $type, $animated = false ) {
  46. $this->imagick = $imagick;
  47. $this->imageFile = $imageFile;
  48. $this->width = $width;
  49. $this->height = $height;
  50. $this->type = $type;
  51. $this->animated = $animated;
  52. }
  53. public function __clone()
  54. {
  55. $copy = clone $this->imagick;
  56. $this->imagick = $copy;
  57. }
  58. /**
  59. * Output a binary raw dump of an image in a specified format.
  60. *
  61. * @param string|ImageType $type Image format of the dump.
  62. *
  63. * @throws \Exception When unsupported type.
  64. */
  65. public function blob( $type = 'PNG' ) {
  66. $this->imagick->setImageFormat($type);
  67. echo $this->imagick->getImageBlob();
  68. }
  69. /**
  70. * @param $imageFile
  71. *
  72. * @return Image
  73. * @throws \Exception
  74. */
  75. public static function createFromFile( $imageFile ){
  76. $imageFile = realpath( $imageFile );
  77. if ( ! file_exists( $imageFile ) ) {
  78. throw new \Exception( sprintf('Could not open image file "%s"', $imageFile) );
  79. }
  80. $imagick = new \Imagick( realpath($imageFile) );
  81. $animated = false;
  82. if ($imagick->getImageIterations() > 0) {
  83. $animated = true;
  84. }
  85. return new self(
  86. $imagick,
  87. $imageFile,
  88. $imagick->getImageWidth(),
  89. $imagick->getImageHeight(),
  90. $imagick->getImageFormat(),
  91. $animated
  92. );
  93. }
  94. /**
  95. * Create an Image from an instance of Imagick.
  96. *
  97. * @param \Imagick $imagick Instance of Imagick.
  98. *
  99. * @return Image
  100. */
  101. public static function createFromCore( $imagick ) {
  102. return new self( $imagick, '', $imagick->getImageWidth(), $imagick->getImageHeight(), $imagick->getImageFormat() );
  103. }
  104. /**
  105. * Create a blank image.
  106. *
  107. * @param int $width Width in pixels.
  108. * @param int $height Height in pixels.
  109. *
  110. * @return self
  111. */
  112. public static function createBlank($width = 1, $height = 1){
  113. $imagick = new \Imagick();
  114. $imagick->newImage($width, $height, new \ImagickPixel('black'));
  115. $imagick->setImageFormat('png'); // Default to PNG.
  116. return new self( $imagick, '', $imagick->getImageWidth(), $imagick->getImageHeight(), $imagick->getImageFormat());
  117. }
  118. /**
  119. * Get Imagick instance
  120. *
  121. * @return \Imagick
  122. */
  123. public function getCore() {
  124. return $this->imagick;
  125. }
  126. /**
  127. * Get image file path.
  128. *
  129. * @return string File path to image.
  130. */
  131. public function getImageFile() {
  132. return $this->imageFile;
  133. }
  134. /**
  135. * Get image width in pixels.
  136. *
  137. * @return int
  138. */
  139. public function getWidth() {
  140. return $this->width;
  141. }
  142. /**
  143. * Get image height in pixels.
  144. *
  145. * @return int
  146. */
  147. public function getHeight() {
  148. return $this->height;
  149. }
  150. /**
  151. * Get image type.
  152. *
  153. * @return string
  154. */
  155. public function getType() {
  156. return $this->type;
  157. }
  158. /**
  159. * Get histogram from an entire image or its sub-region.
  160. *
  161. * @param array|null $slice Array of slice information. array( array( 0,0), array(100,50)) means x,y is 0,0 and width,height is 100,50
  162. *
  163. * @return array Returns array containing RGBA bins array('r'=>array(), 'g'=>array(), 'b'=>array(), 'a'=>array())
  164. */
  165. public function histogram($slice = null)
  166. {
  167. if(null === $slice){
  168. $sliceX = 0;
  169. $sliceY = 0;
  170. $sliceW = $this->getWidth();
  171. $sliceH = $this->getHeight();
  172. } else {
  173. $sliceX = $slice[0][0];
  174. $sliceY = $slice[0][1];
  175. $sliceW = $slice[1][0];
  176. $sliceH = $slice[1][1];
  177. }
  178. $rBin = array();
  179. $gBin = array();
  180. $bBin = array();
  181. $aBin = array();
  182. // Loop using image
  183. $pixelIterator = $this->getCore()->getPixelIterator();
  184. foreach ($pixelIterator as $y => $rows) { /* Loop through pixel rows */
  185. if($y >= $sliceY and $y < $sliceY+$sliceH) {
  186. foreach ($rows as $x => $px) { /* Loop through the pixels in the row (columns) */
  187. if($x >= $sliceX and $x < $sliceX+$sliceW) {
  188. /**
  189. * @var $px \ImagickPixel */
  190. $pixel = $px->getColor();
  191. $r = $pixel['r'];
  192. $g = $pixel['g'];
  193. $b = $pixel['b'];
  194. $a = $pixel['a'];
  195. if ( ! isset($rBin[$r])) {
  196. $rBin[$r] = 1;
  197. } else {
  198. $rBin[$r]++;
  199. }
  200. if ( ! isset($gBin[$g])) {
  201. $gBin[$g] = 1;
  202. } else {
  203. $gBin[$g]++;
  204. }
  205. if ( ! isset($bBin[$b])) {
  206. $bBin[$b] = 1;
  207. } else {
  208. $bBin[$b]++;
  209. }
  210. if ( ! isset($aBin[$a])) {
  211. $aBin[$a] = 1;
  212. } else {
  213. $aBin[$a]++;
  214. }
  215. }
  216. }
  217. }
  218. }
  219. return array(
  220. 'r' => $rBin,
  221. 'g' => $gBin,
  222. 'b' => $bBin,
  223. 'a' => $aBin
  224. );
  225. }
  226. /**
  227. * Returns animated flag.
  228. *
  229. * @return bool True if animated GIF.
  230. */
  231. public function isAnimated() {
  232. return $this->animated;
  233. }
  234. }