api.pixelcraft.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. <?php
  2. /**
  3. * PixelCraft is a lightweight PHP library designed for easy image processing using the GD lib.
  4. * With PixelCraft, you can perform basic image operations such as resizing, cropping, drawing of watermarks, and format conversion.
  5. * The library is characterized by its user-friendly interface and minimal code footprint,
  6. * allowing for quick and efficient image processing in PHP projects.
  7. *
  8. * @package PixelCraft
  9. * @author Rostyslav Haitkulov <info@ubilling.net.ua>
  10. * @see https://github.com/nightflyza/PixelCraft
  11. * @license MIT
  12. */
  13. class PixelCraft {
  14. /**
  15. * Contains image copy to perform some magic on it
  16. *
  17. * @var GDimage
  18. */
  19. protected $image = '';
  20. /**
  21. * Contains image rendering quality
  22. *
  23. * @var int
  24. */
  25. protected $quality = -1;
  26. /**
  27. * Contains loaded image mime type
  28. *
  29. * @var string
  30. */
  31. protected $imageType = '';
  32. /**
  33. * Contains loaded image original width
  34. *
  35. * @var int
  36. */
  37. protected $imageWidth = 0;
  38. /**
  39. * Contains loaded image original height
  40. *
  41. * @var int
  42. */
  43. protected $imageHeight = 0;
  44. /**
  45. * Contains array of custom RGB colors palette as name=>color
  46. *
  47. * @var array
  48. */
  49. protected $colorPalette = array();
  50. /**
  51. * Contains already allocated image colors as name=>colorInt
  52. *
  53. * @var array
  54. */
  55. protected $colorsAllocated = array();
  56. /**
  57. * TTF font path
  58. *
  59. * @var string
  60. */
  61. protected $font = 'skins/OpenSans-Regular.ttf';
  62. /**
  63. * Font size in pt.
  64. *
  65. * @var int
  66. */
  67. protected $fontSize = 10;
  68. /**
  69. * Drawing line width in px
  70. *
  71. * @var int
  72. */
  73. protected $lineWidth = 1;
  74. /**
  75. * Contains watermark image copy
  76. *
  77. * @var GDimage
  78. */
  79. protected $watermark = '';
  80. /**
  81. * Contains currently loaded brush image
  82. *
  83. * @var GDimage
  84. */
  85. protected $brush = '';
  86. /**
  87. * Schweigen im wald
  88. */
  89. public function __construct() {
  90. $this->setDefaultColors();
  91. }
  92. /**
  93. * Sets few default colors to palette
  94. *
  95. * @return void
  96. */
  97. protected function setDefaultColors() {
  98. $this->addColor('white', 255, 255, 255);
  99. $this->addColor('black', 0, 0, 0);
  100. $this->addColor('red', 255, 0, 0);
  101. $this->addColor('green', 0, 255, 0);
  102. $this->addColor('blue', 0, 0, 255);
  103. $this->addColor('yellow', 255, 255, 0);
  104. $this->addColor('grey', 85, 85, 85);
  105. }
  106. /**
  107. * Sets current instance image save/render quality
  108. *
  109. * @param int $quality Deafult -1 means IJG quality value for jpeg or default zlib for png
  110. *
  111. * @return void
  112. */
  113. public function setQuality($quality) {
  114. if (is_int($quality)) {
  115. $this->quality = $quality;
  116. }
  117. }
  118. /**
  119. * Set TTF font path
  120. *
  121. * @param string $font TTF font path
  122. *
  123. * @return void
  124. */
  125. public function setFont($font) {
  126. $this->font = $font;
  127. }
  128. /**
  129. * Set font size in pt.
  130. *
  131. * @param int $fontSize Font size in pt.
  132. *
  133. * @return void
  134. */
  135. public function setFontSize($fontSize) {
  136. $this->fontSize = $fontSize;
  137. }
  138. /**
  139. * Returns current image width
  140. *
  141. * @return int
  142. */
  143. public function getImageWidth() {
  144. return ($this->imageWidth);
  145. }
  146. /**
  147. * Returns current image height
  148. *
  149. * @return int
  150. */
  151. public function getImageHeight() {
  152. return ($this->imageHeight);
  153. }
  154. /**
  155. * Returns loaded image type
  156. *
  157. * @return string
  158. */
  159. public function getImageType() {
  160. return ($this->imageType);
  161. }
  162. /**
  163. * Returns specified image
  164. *
  165. * @param string $filePath
  166. *
  167. * @return array
  168. */
  169. protected function getImageParams($filePath) {
  170. return (@getimagesize($filePath));
  171. }
  172. /**
  173. * Creates or replaces RGB color in palette
  174. *
  175. * @param string $colorName
  176. * @param int $r
  177. * @param int $g
  178. * @param int $b
  179. *
  180. * @return void
  181. */
  182. public function addColor($colorName, $r, $g, $b) {
  183. $this->colorPalette[$colorName] = array('r' => $r, 'g' => $g, 'b' => $b);
  184. }
  185. /**
  186. * Checks is some image valid?
  187. *
  188. * @param string $filePath
  189. * @param array $imageParams
  190. *
  191. * @return bool
  192. */
  193. public function isImageValid($filePath = '', $imageParams = array()) {
  194. $result = false;
  195. if (empty($imageParams) and !empty($filePath)) {
  196. $imageParams = $this->getImageParams($filePath);
  197. }
  198. if (is_array($imageParams)) {
  199. if (isset($imageParams['mime'])) {
  200. if (strpos($imageParams['mime'], 'image/') !== false) {
  201. $result = true;
  202. }
  203. }
  204. }
  205. return ($result);
  206. }
  207. /**
  208. * Returns image type name
  209. *
  210. * @param string $filePath
  211. * @param array $imageParams
  212. *
  213. * @return string
  214. */
  215. protected function detectImageType($filePath = '', $imageParams = array()) {
  216. $result = '';
  217. if ($this->isImageValid($filePath, $imageParams)) {
  218. if (empty($imageParams) and !empty($filePath)) {
  219. $imageParams = $this->getImageParams($filePath);
  220. }
  221. if (is_array($imageParams)) {
  222. $imageType = $imageParams['mime'];
  223. $imageType = str_replace('image/', '', $imageType);
  224. $result = $imageType;
  225. }
  226. }
  227. return ($result);
  228. }
  229. /**
  230. * Loads some image into protected property from file
  231. *
  232. * @param string $fileName readable image file path
  233. * @return bool
  234. */
  235. protected function loadImageFile($filePath, $propertyName = 'image') {
  236. $result = false;
  237. $imageParams = $this->getImageParams($filePath);
  238. $imageType = $this->detectImageType('', $imageParams);
  239. if (!empty($imageType)) {
  240. $loaderFunctionName = 'imagecreatefrom' . $imageType;
  241. if (function_exists($loaderFunctionName)) {
  242. $this->$propertyName = $loaderFunctionName($filePath);
  243. //setting loaded image base props
  244. if ($this->$propertyName != false) {
  245. if ($propertyName == 'image') {
  246. $this->imageWidth = $imageParams[0];
  247. $this->imageHeight = $imageParams[1];
  248. $this->imageType = $imageType;
  249. }
  250. $result = true;
  251. }
  252. } else {
  253. throw new Exception('EX_NOT_SUPPORTED_FILETYPE:' . $imageType);
  254. }
  255. }
  256. return ($result);
  257. }
  258. /**
  259. * Loads some image into protected property from file
  260. *
  261. * @param string $fileName readable image file path
  262. * @return bool
  263. */
  264. public function loadImage($filePath) {
  265. $result = $this->loadImageFile($filePath, 'image');
  266. return ($result);
  267. }
  268. /**
  269. * Loads a instance image from an base64 encoded image string.
  270. *
  271. * @param string $encodedImage The encoded image string.
  272. * @param string $propertyName The name of the property to store the image in. Default is 'image'.
  273. *
  274. * @return bool Returns true if the base image is successfully loaded, false otherwise.
  275. */
  276. public function loadBaseImage($encodedImage, $propertyName = 'image') {
  277. $result = false;
  278. if (!empty($encodedImage)) {
  279. $decodedImage = base64_decode($encodedImage);
  280. if ($decodedImage) {
  281. $imageParams = getimagesizefromstring($decodedImage);
  282. $imageType = $this->detectImageType('', $imageParams);
  283. if (!empty($imageType)) {
  284. $this->$propertyName = imagecreatefromstring($decodedImage);
  285. if ($this->$propertyName != false) {
  286. if ($propertyName == 'image') {
  287. $this->imageWidth = $imageParams[0];
  288. $this->imageHeight = $imageParams[1];
  289. $this->imageType = $imageType;
  290. }
  291. $result = true;
  292. }
  293. }
  294. }
  295. }
  296. return ($result);
  297. }
  298. /**
  299. * Loads some watermark image into protected property from file
  300. *
  301. * @param string $fileName readable image file path
  302. * @return bool
  303. */
  304. public function loadWatermark($filePath) {
  305. $result = $this->loadImageFile($filePath, 'watermark');
  306. if ($result) {
  307. imagealphablending($this->watermark, false);
  308. }
  309. return ($result);
  310. }
  311. /**
  312. * Renders current instance image into browser or specified file path
  313. *
  314. * @param string $fileName writable file path with name or null to browser rendering
  315. * @param string $type image type to save, like jpeg, png, gif...
  316. *
  317. * @return bool
  318. */
  319. public function saveImage($fileName = null, $type = 'png') {
  320. $result = false;
  321. if ($this->image) {
  322. $saveFunctionName = 'image' . $type;
  323. if (function_exists($saveFunctionName)) {
  324. //custom header on browser output
  325. if (!$fileName) {
  326. header('Content-Type: image/' . $type);
  327. }
  328. if ($type == 'jpeg' or $type == 'png') {
  329. if ($type == 'png') {
  330. imagesavealpha($this->image, true);
  331. }
  332. $result = $saveFunctionName($this->image, $fileName, $this->quality);
  333. } else {
  334. $result = $saveFunctionName($this->image, $fileName);
  335. }
  336. //memory free
  337. imagedestroy($this->image);
  338. //droppin image props
  339. $this->imageWidth = 0;
  340. $this->imageHeight = 0;
  341. $this->imageType = '';
  342. //nothing else matters
  343. if ($fileName === false) {
  344. die();
  345. }
  346. } else {
  347. throw new Exception('EX_NOT_SUPPORTED_FILETYPE:' . $type);
  348. }
  349. } else {
  350. throw new Exception('EX_VOID_IMAGE');
  351. }
  352. return ($result);
  353. }
  354. /**
  355. * Returns current instance image as base64 encoded text
  356. *
  357. * @param string $type image mime type
  358. * @param bool $htmlData data ready to embed as img src HTML base64 data (data URI scheme)
  359. *
  360. * @return void
  361. */
  362. public function getImageBase($type = 'png', $htmlData = false) {
  363. $result = '';
  364. if ($this->image) {
  365. $saveFunctionName = 'image' . $type;
  366. if (function_exists($saveFunctionName)) {
  367. ob_start();
  368. if ($type == 'jpeg' or $type == 'png') {
  369. if ($type == 'png') {
  370. imagesavealpha($this->image, true);
  371. }
  372. }
  373. $result = $saveFunctionName($this->image, null, $this->quality);
  374. //memory free
  375. imagedestroy($this->image);
  376. //droppin image props
  377. $this->imageWidth = 0;
  378. $this->imageHeight = 0;
  379. $this->imageType = '';
  380. $imageBody = ob_get_contents();
  381. ob_end_clean();
  382. if (!empty($imageBody)) {
  383. $result = base64_encode($imageBody);
  384. // print($imageBody);
  385. }
  386. //optional html embed data
  387. if ($htmlData) {
  388. $result = 'data:image/' . $type . ';charset=utf-8;base64,' . $result;
  389. }
  390. } else {
  391. throw new Exception('EX_NOT_SUPPORTED_FILETYPE:' . $type);
  392. }
  393. } else {
  394. throw new Exception('EX_VOID_IMAGE');
  395. }
  396. return ($result);
  397. }
  398. /**
  399. * Renders current instance image into browser
  400. *
  401. * @param string $type
  402. *
  403. * @return void
  404. */
  405. public function renderImage($type = 'png') {
  406. $this->saveImage(null, $type);
  407. }
  408. /**
  409. * Creates new empty true-color image
  410. *
  411. * @return void
  412. */
  413. public function createImage($width, $height) {
  414. $this->image = imagecreatetruecolor($width, $height);
  415. $this->imageWidth = $width;
  416. $this->imageHeight = $height;
  417. }
  418. /**
  419. * Scales image to some scale
  420. *
  421. * @param float $scale something like 0.5 for 50% or 2 for 2x scale
  422. *
  423. * @return void
  424. */
  425. public function scale($scale) {
  426. if ($this->imageWidth and $this->imageHeight) {
  427. if ($scale != 1) {
  428. $nWidth = $this->imageWidth * $scale;
  429. $nHeight = $this->imageHeight * $scale;
  430. $imageCopy = imagecreatetruecolor($nWidth, $nHeight);
  431. imagealphablending($imageCopy, false);
  432. imagesavealpha($imageCopy, true);
  433. imagecopyresized($imageCopy, $this->image, 0, 0, 0, 0, $nWidth, $nHeight, $this->imageWidth, $this->imageHeight);
  434. $this->image = $imageCopy;
  435. $this->imageWidth = $nWidth;
  436. $this->imageHeight = $nHeight;
  437. }
  438. }
  439. }
  440. /**
  441. * Resizes image to some new dimensions
  442. *
  443. * @param int $width
  444. * @param int $height
  445. *
  446. * @return void
  447. */
  448. public function resize($width, $height) {
  449. if ($this->imageWidth and $this->imageHeight) {
  450. $imageResized = imagescale($this->image, $width, $height);
  451. $this->image = $imageResized;
  452. $this->imageWidth = $width;
  453. $this->imageHeight = $height;
  454. }
  455. }
  456. /**
  457. * Crops image to new dimensions starting from 0x0
  458. *
  459. * @return void
  460. */
  461. public function crop($width, $height) {
  462. if ($this->imageWidth and $this->imageHeight) {
  463. $imageCropped = imagecrop($this->image, array('x' => 0, 'y' => 0, 'width' => $width, 'height' => $height));
  464. $this->image = $imageCropped;
  465. $this->imageWidth = $width;
  466. $this->imageHeight = $height;
  467. }
  468. }
  469. /**
  470. * Crops image to selected region by coords
  471. *
  472. * @return void
  473. */
  474. public function cropRegion($x1, $y1, $x2, $y2) {
  475. if ($this->imageWidth and $this->imageHeight) {
  476. $imageCropped = imagecrop($this->image, array('x' => $x1, 'y' => $y1, 'width' => $x2, 'height' => $y2));
  477. $this->image = $imageCropped;
  478. $this->imageWidth = $x2;
  479. $this->imageHeight = $y2;
  480. }
  481. }
  482. /**
  483. * Allocates and returns some image color by its name
  484. *
  485. * @param string $colorName
  486. *
  487. * @return int
  488. */
  489. protected function allocateColor($colorName) {
  490. $result = 0;
  491. if (isset($this->colorPalette[$colorName])) {
  492. $colorData = $this->colorPalette[$colorName];
  493. if (isset($this->colorsAllocated[$colorName])) {
  494. $result = $this->colorsAllocated[$colorName];
  495. } else {
  496. $result = imagecolorallocate($this->image, $colorData['r'], $colorData['g'], $colorData['b']);
  497. $this->colorsAllocated[$colorName] = $result;
  498. }
  499. } else {
  500. throw new Exception('EX_COLOR_NOT_EXISTS:' . $colorName);
  501. }
  502. return ($result);
  503. }
  504. /**
  505. * Fills image with some color from palette
  506. *
  507. * @param string $colorName
  508. *
  509. * @return void
  510. */
  511. public function fill($colorName) {
  512. imagefill($this->image, 0, 0, $this->allocateColor($colorName));
  513. }
  514. /**
  515. * Draws pixel on X/Y coords with some color from palette
  516. *
  517. * @param int y
  518. * @param int x
  519. * @param string $colorName
  520. *
  521. * @return void
  522. */
  523. public function drawPixel($x, $y, $colorName) {
  524. imagesetpixel($this->image, $x, $y, $this->allocateColor($colorName));
  525. }
  526. /**
  527. * Prints some text string at specified X/Y coords with default font
  528. *
  529. * @param int $x
  530. * @param int $y
  531. * @param string $text
  532. * @param string $colorName
  533. * @param int $size=1
  534. * @param bool $vertical
  535. *
  536. * @return void
  537. */
  538. public function drawString($x, $y, $text, $colorName, $size = 1, $vertical = false) {
  539. if (!empty($text)) {
  540. if ($vertical) {
  541. imagestringup($this->image, $size, $x, $y, $text, $this->allocateColor($colorName));
  542. } else {
  543. imagestring($this->image, $size, $x, $y, $text, $this->allocateColor($colorName));
  544. }
  545. }
  546. }
  547. /**
  548. * Write text to the image using TrueType fonts
  549. *
  550. * @param int $x
  551. * @param int $y
  552. * @param string $text
  553. * @param string $colorName
  554. *
  555. * @return void
  556. */
  557. public function drawText($x, $y, $text, $colorName) {
  558. if (!empty($text)) {
  559. imagettftext($this->image, $this->fontSize, 0, $x, $y, $this->allocateColor($colorName), $this->font, $text);
  560. }
  561. }
  562. /**
  563. * Returns font size that fits into image width
  564. *
  565. * @param int $fontSize font size that required to fit text
  566. * @param string $text text data that required to fit
  567. * @param int $padding text padding in px
  568. *
  569. * @return int
  570. */
  571. protected function guessFontSize($fontSize, $text, $padding) {
  572. $box = imageftbbox($fontSize, 0, $this->font, $text);
  573. $boxWidth = $box[4] - $box[6];
  574. $imageWidth = $this->imageWidth - ($padding * 2);
  575. if ($boxWidth > $imageWidth) {
  576. $fontSize = $fontSize - 1;
  577. return $this->guessFontSize($fontSize, $text, $padding);
  578. }
  579. return ($fontSize);
  580. }
  581. /**
  582. * Write single text to the image using TrueType font with auto size selection
  583. *
  584. * @param int $y
  585. * @param int $padding
  586. * @param string $text
  587. * @param string $colorName
  588. * @param string $outlineColor
  589. *
  590. * @return void
  591. */
  592. public function drawTextAutoSize($y, $padding = 10, $text = '', $colorName = '', $outlineColor = '') {
  593. if (!empty($text)) {
  594. $defaultFontSize = 40;
  595. $border = 1;
  596. $x = $padding;
  597. $colorName = (empty($colorName)) ? 'white' : $colorName;
  598. $outlineColor = (empty($outlineColor)) ? 'black' : $outlineColor;
  599. //guessing font size
  600. $fontSize = $this->guessFontSize($defaultFontSize, $text, $padding);
  601. //drawing outline if required
  602. if ($outlineColor) {
  603. for ($c1 = ($x - abs($border)); $c1 <= ($x + abs($border)); $c1++) {
  604. for ($c2 = ($y - abs($border)); $c2 <= ($y + abs($border)); $c2++) {
  605. imagettftext($this->image, $fontSize, 0, $c1, $c2, $this->allocateColor($outlineColor), $this->font, $text);
  606. }
  607. }
  608. }
  609. //and text with selected color
  610. imagettftext($this->image, $fontSize, 0, $x, $y, $this->allocateColor($colorName), $this->font, $text);
  611. }
  612. }
  613. /**
  614. * Set the thickness for line drawing in px
  615. *
  616. * @param int $lineWidth
  617. *
  618. * @return void
  619. */
  620. public function setLineWidth($lineWidth) {
  621. $this->lineWidth = $lineWidth;
  622. imagesetthickness($this->image, $this->lineWidth);
  623. }
  624. /**
  625. * Draws filled rectangle
  626. *
  627. * @param int $x1
  628. * @param int $y1
  629. * @param int $x2
  630. * @param int $y2
  631. * @param string $colorName
  632. *
  633. * @return void
  634. */
  635. public function drawRectangle($x1, $y1, $x2, $y2, $colorName) {
  636. if (isset($this->colorPalette[$colorName])) {
  637. $colorData = $this->colorPalette[$colorName];
  638. if (isset($this->colorsAllocated[$colorName])) {
  639. $drawingColor = $this->colorsAllocated[$colorName];
  640. } else {
  641. $drawingColor = imagecolorallocate($this->image, $colorData['r'], $colorData['g'], $colorData['b']);
  642. $this->colorsAllocated[$colorName] = $drawingColor;
  643. }
  644. imagefilledrectangle($this->image, $x1, $y1, $x2, $y2, $drawingColor);
  645. } else {
  646. throw new Exception('EX_COLOR_NOT_EXISTS:' . $colorName);
  647. }
  648. }
  649. /**
  650. * Draws a line using some color
  651. *
  652. * @param int $x1
  653. * @param int $y1
  654. * @param int $x2
  655. * @param int $y2
  656. * @param string $colorName
  657. *
  658. * @return void
  659. */
  660. public function drawLine($x1, $y1, $x2, $y2, $colorName) {
  661. imageline($this->image, $x1, $y1, $x2, $y2, $this->allocateColor($colorName));
  662. }
  663. /**
  664. * Draws a line using preloaded brush
  665. *
  666. * @param int $x1
  667. * @param int $y1
  668. * @param int $x2
  669. * @param int $y2
  670. *
  671. * @return void
  672. */
  673. public function drawLineBrush($x1, $y1, $x2, $y2) {
  674. imageline($this->image, $x1, $y1, $x2, $y2, IMG_COLOR_BRUSHED);
  675. }
  676. /**
  677. * Puts preloaded watermark on base image
  678. *
  679. * @param int $stretch=true
  680. * @param int $x=0
  681. * @param int $y=0
  682. *
  683. * @return void
  684. */
  685. public function drawWatermark($stretch = true, $x = 0, $y = 0) {
  686. imagealphablending($this->watermark, false);
  687. $watermarkWidth = imagesx($this->watermark);
  688. $watermarkHeight = imagesy($this->watermark);
  689. if ($stretch) {
  690. imagecopyresampled($this->image, $this->watermark, $x, $y, 0, 0, $this->imageWidth, $this->imageHeight, $watermarkWidth, $watermarkHeight);
  691. } else {
  692. imagecopy($this->image, $this->watermark, $x, $y, 0, 0, $watermarkWidth, $watermarkHeight);
  693. }
  694. }
  695. /**
  696. * Applies pixelation filter
  697. *
  698. * @param int $blockSize
  699. * @param bool $smooth
  700. *
  701. * @return void
  702. */
  703. public function pixelate($blockSize, $smooth = true) {
  704. imagefilter($this->image, IMG_FILTER_PIXELATE, $blockSize, $smooth);
  705. }
  706. /**
  707. * Applies image filters set to current instance base image
  708. *
  709. * @param array|int $filterSet must contains array of filters as index=>(IMAGE_FILTER=>argsArray)
  710. *
  711. * @return void
  712. */
  713. public function imageFilters($filterSet = array()) {
  714. if (!empty($filterSet)) {
  715. foreach ($filterSet as $eachFilterIdx => $eachFilterData) {
  716. if (is_array($eachFilterData)) {
  717. foreach ($eachFilterData as $eachFilter => $eachFilterArgs/* */) {
  718. if (is_array($eachFilterArgs)) {
  719. $filterArgsTmp = array();
  720. $filterArgsTmp[] = $this->image;
  721. $filterArgsTmp[] = $eachFilter;
  722. foreach ($eachFilterArgs as $io => $each) {
  723. $filterArgsTmp[] = $each;
  724. }
  725. //not using just "..." arg unpack operator here due PHP <5.6 compat
  726. call_user_func_array('imagefilter', $filterArgsTmp);
  727. } else {
  728. imagefilter($this->image, $eachFilter, $eachFilterArgs);
  729. }
  730. }
  731. }
  732. }
  733. }
  734. }
  735. /**
  736. * Returns RGB values for some specified image pixel as r/g/b/a(lpha)
  737. *
  738. * @return array
  739. */
  740. public function getPixelColor($x, $y) {
  741. $result = array();
  742. $rgb = imagecolorat($this->image, $x, $y);
  743. $components = imagecolorsforindex($this->image, $rgb);
  744. $result['r'] = $components['red'];
  745. $result['g'] = $components['green'];
  746. $result['b'] = $components['blue'];
  747. $result['a'] = $components['alpha'];
  748. return ($result);
  749. }
  750. /**
  751. * Converts RGB components array into hex string
  752. *
  753. * @param array $rgb RGB/RGBa components array
  754. *
  755. * @return string
  756. */
  757. public function rgbToHex($rgb) {
  758. $result = '';
  759. if (!empty($rgb)) {
  760. $result = sprintf("#%02x%02x%02x", $rgb['r'], $rgb['g'], $rgb['b']);
  761. }
  762. return ($result);
  763. }
  764. /**
  765. * Converts hex color string to RGB components array
  766. *
  767. * @param string $hex hex string as RRGGBB
  768. *
  769. * @return array
  770. */
  771. public function hexToRgb($hex) {
  772. $result = '';
  773. if (!empty($hex)) {
  774. $hex = str_replace('#', '', $hex);
  775. $r = hexdec(substr($hex, 0, 2));
  776. $g = hexdec(substr($hex, 2, 2));
  777. $b = hexdec(substr($hex, 4, 2));
  778. $result = array('r' => $r, 'g' => $g, 'b' => $b);
  779. }
  780. return ($result);
  781. }
  782. /**
  783. * Calculates the brightness value of an RGB color.
  784. *
  785. * @param array $rgb The RGB color values as an associative array with keys 'r', 'g', and 'b'.
  786. *
  787. * @return int The brightness value of the RGB color.
  788. */
  789. public function rgbToBrightness($rgb) {
  790. $result = round(($rgb['r'] + $rgb['g'] + $rgb['b']) / 3);
  791. return ($result);
  792. }
  793. /**
  794. * Returns color map for current intance image as array(y,x)=>color
  795. *
  796. * @param bool $hex returns map values as rrggbb hex values or raw rgba components
  797. *
  798. * @return array
  799. */
  800. public function getColorMap($hex = true) {
  801. $result = array();
  802. for ($x = 0; $x < $this->imageWidth; $x++) {
  803. for ($y = 0; $y < $this->imageHeight; $y++) {
  804. $rgb = $this->getPixelColor($x, $y);
  805. if ($hex) {
  806. $result[$y][$x] = $this->rgbToHex($rgb);
  807. } else {
  808. $result[$y][$x] = $rgb;
  809. }
  810. }
  811. }
  812. return ($result);
  813. }
  814. /**
  815. * Calculates the brightness of a pixel at the specified coordinates.
  816. *
  817. * @param int $x The x-coordinate of the pixel.
  818. * @param int $y The y-coordinate of the pixel.
  819. *
  820. * @return int The brightness value of the pixel.
  821. */
  822. public function getPixelBrightness($x, $y) {
  823. $result = false;
  824. $pixelColor = $this->getPixelColor($x, $y);
  825. $result = $this->rgbToBrightness($pixelColor);
  826. return ($result);
  827. }
  828. /**
  829. * Rotates the image by the specified angle clockwise
  830. *
  831. * @param int $angle The angle in degrees to rotate the image.
  832. *
  833. * @return void
  834. */
  835. public function rotate($angle) {
  836. $this->image = imagerotate($this->image, 360 - $angle, 0);
  837. }
  838. /**
  839. * Sets the brush for the image using the specified file path.
  840. *
  841. * @param string $filePath The path to the image file to be used as a brush.
  842. *
  843. * @return bool
  844. */
  845. public function setBrush($filePath) {
  846. $result = $this->loadImageFile($filePath, 'brush');
  847. if ($result) {
  848. imagesetbrush($this->image, $this->brush);
  849. }
  850. return ($result);
  851. }
  852. /**
  853. * Draw a partial arc and fill it
  854. *
  855. * @param int $x The x-coordinate of the center.
  856. * @param int $y The y-coordinate of the center.
  857. * @param int $width The width of the arc.
  858. * @param int $height The height of the arc.
  859. * @param int $startAngle The start angle of the arc in degrees.
  860. * @param int $endAngle The end angle of the arc in degrees.
  861. * @param string $colorName The name of the color to use for the arc.
  862. * @param int $style The style of the arc. Available: IMG_ARC_PIE, IMG_ARC_CHORD, IMG_ARC_NOFILL, IMG_ARC_EDGED
  863. *
  864. * @return void
  865. */
  866. public function drawArc($x, $y, $width, $height, $startAngle, $endAngle, $colorName, $style = IMG_ARC_PIE) {
  867. imagefilledarc($this->image, $x, $y, $width, $height, $startAngle, $endAngle, $this->allocateColor($colorName), $style);
  868. }
  869. }