ImageTest.php 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  1. <?php
  2. /**
  3. * Testing Class for Image Manipulation
  4. *
  5. * @package KO7/Image/Test
  6. *
  7. * @group ko7
  8. * @group ko7.image
  9. *
  10. * @copyright (c) 2007-2016 Kohana Team
  11. * @copyright (c) since 2016 Koseven Team
  12. * @license https://koseven.dev/LICENSE
  13. */
  14. class KO7_ImageTest extends Unittest_TestCase {
  15. /**
  16. * Holds available Image driver - we will test against them
  17. * this is useful, because you can test your own driver by simply extending this class and
  18. * adding it here.
  19. */
  20. public static $drivers = [];
  21. /**
  22. * File Extensions to test.
  23. * This is here so you can change/override it on your local machine
  24. * if some of those types are not supported by your system.
  25. *
  26. * @var array
  27. */
  28. public static $extensions = [
  29. 'webp',
  30. 'bmp',
  31. 'gif',
  32. 'jpg',
  33. 'png'
  34. ];
  35. /**
  36. * Default values for the environment
  37. * @var array
  38. */
  39. protected $environmentDefault = [
  40. 'image.default_driver' => NULL
  41. ];
  42. /**
  43. * KO7_ImageTest constructor.
  44. *
  45. * We need to evaluate this in the constructor because dataProviders run before
  46. * setUp() and setUpBeforeClass()
  47. *
  48. * @param null $name
  49. * @param array $data
  50. * @param string $dataName
  51. */
  52. public function __construct($name = NULL, array $data = [], $dataName = '')
  53. {
  54. // Checks if php-gd is loaded
  55. if (extension_loaded('gd'))
  56. {
  57. // Add if not there
  58. if ( ! in_array('GD', static::$drivers, TRUE)) {
  59. static::$drivers[] = 'GD';
  60. }
  61. // Don't test webp files if they are unsupported
  62. if (in_array('webp', static::$extensions, TRUE) && ! gd_info()['WebP Support'])
  63. {
  64. unset(static::$extensions[array_search('webp', static::$extensions, TRUE)]);
  65. }
  66. // Don't test bmp files if they are unsupported
  67. if (in_array('bmp', static::$extensions, TRUE) && ! gd_info()['BMP Support'])
  68. {
  69. unset(static::$extensions[ array_search('bmp', static::$extensions, TRUE)]);
  70. }
  71. }
  72. // checks if php-imagick is loaded
  73. if (extension_loaded('imagick'))
  74. {
  75. // Add if not there
  76. if ( ! in_array('Imagick', static::$drivers, TRUE)) {
  77. static::$drivers[] = 'Imagick';
  78. }
  79. // Don't test webp files if they are unsupported
  80. if (in_array('webp', static::$extensions, TRUE) &&
  81. empty(Imagick::queryFormats("WEBP")))
  82. {
  83. unset(static::$extensions[array_search('webp', static::$extensions, TRUE)]);
  84. }
  85. // Don't test bmp files if they are unsupported
  86. if (in_array('bmp', static::$extensions, TRUE) &&
  87. empty(Imagick::queryFormats("BMP")))
  88. {
  89. unset(static::$extensions[array_search('bmp', static::$extensions, TRUE)]);
  90. }
  91. }
  92. // Skip test if non of the drivers are available
  93. if (empty(static::$drivers))
  94. {
  95. $this->markTestSkipped('Please either enable php-gd or php-imagick extension.');
  96. }
  97. parent::__construct($name, $data, $dataName);
  98. }
  99. /**
  100. * We will create some test files inside the cache_dir, so let's clean it after we are done
  101. * @throws KO7_Exception
  102. * @throws ReflectionException
  103. */
  104. public function tearDown(): void
  105. {
  106. $this->cleanCacheDir();
  107. parent::tearDown();
  108. }
  109. /**
  110. * Data provider for test_invalid_driver
  111. *
  112. * @return array
  113. */
  114. public function provider_invalid_driver() : array
  115. {
  116. return
  117. [
  118. [
  119. NULL
  120. ],
  121. [
  122. 'Arr'
  123. ],
  124. [
  125. 'Invalid_Class_Name_For_Image_Driver'
  126. ]
  127. ];
  128. }
  129. /**
  130. * Test for Image::factory() method.
  131. * Test instance with Non-existent / invalid drivers
  132. *
  133. * @dataProvider provider_invalid_driver
  134. *
  135. * @param string $driver Driver to test against
  136. *
  137. * @throws Image_Exception
  138. * @throws KO7_Exception
  139. */
  140. public function test_invalid_driver(?string $driver) : void
  141. {
  142. // Expect an Image_Exception to be thrown
  143. $this->expectException(Image_Exception::class);
  144. // Instance with wrong driver
  145. Image::factory('', $driver);
  146. }
  147. /**
  148. * Provider for test_extension_to_image_type
  149. * @return array
  150. */
  151. public function provider_extension_to_image_type() : array
  152. {
  153. return [
  154. [
  155. '.jpg',
  156. IMAGETYPE_JPEG
  157. ],
  158. [
  159. 'png',
  160. IMAGETYPE_PNG
  161. ],
  162. [
  163. 'jpeg',
  164. IMAGETYPE_JPEG
  165. ],
  166. [
  167. '.gif',
  168. IMAGETYPE_GIF
  169. ],
  170. [
  171. 'webp',
  172. IMAGETYPE_WEBP
  173. ]
  174. ];
  175. }
  176. /**
  177. * Test for the KO7_Image::extension_to_image_type method
  178. *
  179. * @dataProvider provider_extension_to_image_type
  180. *
  181. * @param string $ext Extension to test
  182. * @param integer $expected_type Expected extension Type
  183. */
  184. public function test_extension_to_image_type(string $ext, int $expected_type) : void
  185. {
  186. $type = KO7_Image::extension_to_image_type($ext);
  187. $this->assertSame($type, $expected_type);
  188. }
  189. /**
  190. * Data provider for test_save_and_load
  191. *
  192. * For detailed description, look into the tests doc-comment.
  193. *
  194. * @return array
  195. */
  196. public function provider_save_and_load() : array
  197. {
  198. $return = [];
  199. // Provide Path to a valid filename
  200. $validFile = MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_image';
  201. // Extensions to test
  202. $extensions = static::$extensions;
  203. foreach (static::$drivers as $driver)
  204. {
  205. // Test file with different (common) extensions
  206. foreach ($extensions as $extension)
  207. {
  208. $return[] = [
  209. [
  210. 'file' => $validFile . '.' . $extension,
  211. 'driver' => $driver
  212. ],
  213. [
  214. 'ext' => $extension
  215. ]
  216. ];
  217. }
  218. // Test saving a file as different format
  219. $return[] = [
  220. [
  221. 'file' => $validFile . '.png',
  222. 'driver' => $driver,
  223. 'save_path' => KO7::$cache_dir.DIRECTORY_SEPARATOR.'test.jpg'
  224. ],
  225. [
  226. 'ext' => 'jpg'
  227. ]
  228. ];
  229. // Test file without an extension
  230. $return[] = [
  231. [
  232. 'file' => MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_image',
  233. 'driver' => $driver
  234. ],
  235. [
  236. 'ext' => 'gif'
  237. ]
  238. ];
  239. // Test invalid file
  240. $return[] = [
  241. [
  242. 'file' => MODPATH . 'image'.DIRECTORY_SEPARATOR.'thisissoinvalid.jpg',
  243. 'driver' => $driver
  244. ],
  245. [
  246. 'exception' => TRUE
  247. ]
  248. ];
  249. // Test none-image file
  250. $return[] = [
  251. [
  252. 'file' => MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'unsupported',
  253. 'driver' => $driver
  254. ],
  255. [
  256. 'exception' => TRUE
  257. ]
  258. ];
  259. // Test non-existing save path
  260. $return[] = [
  261. [
  262. 'file' => $validFile,
  263. 'driver' => $driver,
  264. 'save_path' => KO7::$cache_dir.'/non_existing_directory/non_existing_file.jpg'
  265. ],
  266. [
  267. 'exception' => TRUE
  268. ]
  269. ];
  270. }
  271. return $return;
  272. }
  273. /**
  274. * Tests for Image::factory and Image::save() method.
  275. *
  276. * This test performs multiple smaller tasks:
  277. *
  278. * - It tests loading and saving different formats (webp, jpg, etc..)
  279. * - It tests overwriting images
  280. * - It tests if you load an image and save it afterwards, if they still share the same type
  281. * - It tests opening invalid image files
  282. * - It tests opening and saving image files which do not have an extension in their filename
  283. * - It tests opening a file and saving it as different format
  284. *
  285. * @dataProvider provider_save_and_load
  286. *
  287. * @param array $input Input Variables (File, Driver, etc..)
  288. * @param array $expected Expected Results (Exceptions, Files, etc..)
  289. *
  290. * @throws Image_Exception
  291. * @throws KO7_Exception
  292. */
  293. public function test_save_and_load(array $input, array $expected) : void
  294. {
  295. // Expect an exception?
  296. if (isset($expected['exception']))
  297. {
  298. $this->expectException(Image_Exception::class);
  299. }
  300. // Load image
  301. $image = Image::factory($input['file'], $input['driver']);
  302. // Set Path where we save the image
  303. $save_path = $input['save_path'] ?? KO7::$cache_dir.DIRECTORY_SEPARATOR.'test_image';
  304. // Check if Image got saved successfully
  305. $this->assertTrue($image->save($save_path));
  306. // Check if Image truly exists
  307. $this->assertTrue(is_file($save_path));
  308. // Check if saved file has the same type as expected
  309. $this->assertSame(KO7_Image::extension_to_image_type($expected['ext']), getimagesize($save_path)[2]);
  310. }
  311. /**
  312. * Data Provider for test_resize
  313. *
  314. * @return array
  315. */
  316. public function provider_resize() : array
  317. {
  318. // Init Return array
  319. $return = [];
  320. // image to test against
  321. $image = MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_crop.jpg';
  322. foreach (static::$drivers as $driver)
  323. {
  324. // Try without height and width
  325. $return[] = [
  326. [
  327. 'file' => $image,
  328. 'driver' => $driver,
  329. 'height' => NULL,
  330. 'width' => NULL,
  331. 'master' => NULL
  332. ],
  333. [
  334. 'exception' => TRUE
  335. ]
  336. ];
  337. // Try without master but with width and height (AUTO)
  338. $return[] = [
  339. [
  340. 'file' => $image,
  341. 'driver' => $driver,
  342. 'width' => 70,
  343. 'height' => 50,
  344. 'master' => NULL
  345. ],
  346. [
  347. 'width' => 25,
  348. 'height' => 50
  349. ]
  350. ];
  351. // Try without master but with width
  352. $return[] = [
  353. [
  354. 'file' => $image,
  355. 'driver' => $driver,
  356. 'width' => 70,
  357. 'height' => NULL,
  358. 'master' => NULL
  359. ],
  360. [
  361. 'width' => 70,
  362. 'height' => 140
  363. ]
  364. ];
  365. // Try without master but with height
  366. $return[] = [
  367. [
  368. 'file' => $image,
  369. 'driver' => $driver,
  370. 'width' => NULL,
  371. 'height' => 50,
  372. 'master' => NULL
  373. ],
  374. [
  375. 'width' => 25,
  376. 'height' => 50
  377. ]
  378. ];
  379. // Try without master but with width and height (other reduction ratio)
  380. $return[] = [
  381. [
  382. 'file' => $image,
  383. 'driver' => $driver,
  384. 'height' => 50,
  385. 'width' => 20,
  386. 'master' => NULL
  387. ],
  388. [
  389. 'width' => 20,
  390. 'height' => 40
  391. ]
  392. ];
  393. // Try with master Inverse
  394. $return[] = [
  395. [
  396. 'file' => $image,
  397. 'driver' => $driver,
  398. 'height' => 50,
  399. 'width' => 70,
  400. 'master' => Image::INVERSE
  401. ],
  402. [
  403. 'width' => 70,
  404. 'height' => 140
  405. ]
  406. ];
  407. // Try with master None and width and height
  408. $return[] = [
  409. [
  410. 'file' => $image,
  411. 'driver' => $driver,
  412. 'height' => 50,
  413. 'width' => 70,
  414. 'master' => Image::NONE
  415. ],
  416. [
  417. 'width' => 70,
  418. 'height' => 50
  419. ]
  420. ];
  421. // Try with master None and width
  422. $return[] = [
  423. [
  424. 'file' => $image,
  425. 'driver' => $driver,
  426. 'height' => NULL,
  427. 'width' => 70,
  428. 'master' => Image::NONE
  429. ],
  430. [
  431. 'width' => 70,
  432. 'height' => 200
  433. ]
  434. ];
  435. // Try with master None and height
  436. $return[] = [
  437. [
  438. 'file' => $image,
  439. 'driver' => $driver,
  440. 'height' => 20,
  441. 'width' => NULL,
  442. 'master' => Image::NONE
  443. ],
  444. [
  445. 'width' => 100,
  446. 'height' => 20
  447. ]
  448. ];
  449. // Try with invalid master
  450. $return[] = [
  451. [
  452. 'file' => $image,
  453. 'driver' => $driver,
  454. 'height' => 20,
  455. 'width' => NULL,
  456. 'master' => 0x445
  457. ],
  458. [
  459. 'exception' => TRUE
  460. ]
  461. ];
  462. }
  463. return $return;
  464. }
  465. /**
  466. * Test for Image::resize() method
  467. *
  468. * @dataProvider provider_resize
  469. *
  470. * @param array $input
  471. * @param array $expected
  472. *
  473. * @throws Image_Exception
  474. * @throws KO7_Exception
  475. */
  476. public function test_resize(array $input, array $expected) : void
  477. {
  478. // Do we expect an exception?
  479. if (isset($expected['exception']))
  480. {
  481. $this->expectException(Image_Exception::class);
  482. }
  483. // Load image
  484. $image = Image::factory($input['file'], $input['driver']);
  485. // Resize
  486. $result = $image->resize($input['width'], $input['height'], $input['master']);
  487. // Compare new image dimensions to expected ones
  488. $this->assertSame(round($expected['width']), round($result->width));
  489. $this->assertSame(round($expected['height']), round($result->height));
  490. }
  491. /**
  492. * Data Provider for test_crop
  493. *
  494. * @return array
  495. */
  496. public function provider_crop() : array
  497. {
  498. // Init return array
  499. $return = [];
  500. // image to test against
  501. foreach (static::$drivers as $driver)
  502. {
  503. // Test with correct with and height
  504. $return[] = [
  505. 50,
  506. 100,
  507. NULL,
  508. NULL,
  509. $driver,
  510. [
  511. 'width' => 50,
  512. 'height' => 100
  513. ]
  514. ];
  515. // Test with higher width and height then actual Image size
  516. $return[] = [
  517. 300,
  518. 400,
  519. NULL,
  520. NULL,
  521. $driver,
  522. [
  523. 'width' => 100,
  524. 'height' => 200
  525. ]
  526. ];
  527. // Test with reverse offset
  528. $return[] = [
  529. 30,
  530. 50,
  531. TRUE,
  532. TRUE,
  533. $driver,
  534. [
  535. 'width' => 30,
  536. 'height' => 50
  537. ]
  538. ];
  539. // Test with positive offset
  540. $return[] = [
  541. 100,
  542. 200,
  543. 10,
  544. 10,
  545. $driver,
  546. [
  547. 'width' => 90,
  548. 'height' => 190
  549. ]
  550. ];
  551. // Test with negative offset
  552. $return[] = [
  553. 100,
  554. 200,
  555. -10,
  556. -15,
  557. $driver,
  558. [
  559. 'width' => 90,
  560. 'height' => 185
  561. ]
  562. ];
  563. }
  564. return $return;
  565. }
  566. /**
  567. * Test for Image::crop() method.
  568. *
  569. * This test as quite similar to resize test, since we can not assure that
  570. * offset cropping, etc.. worked correctly. Only way to archive this would be KAT and comparing
  571. * - for example - the blob hashes. Problem there is that for example php-gd adds headers to the image
  572. * and each header is different from (even minor) version to version, which would also change the image blob.
  573. * Therefore we can't really test it that way but at least we can test if the cropping itself worked.
  574. *
  575. * @dataProvider provider_crop
  576. *
  577. * @param int|null $width Desired width
  578. * @param int|null $height Desired height
  579. * @param mixed $offx Offset from left
  580. * @param mixed $offy Offset from top
  581. * @param string $driver Image Driver to use
  582. * @param array $expected Expected image width and height
  583. *
  584. * @throws Image_Exception
  585. * @throws KO7_Exception
  586. */
  587. public function test_crop(?int $width, ?int $height, $offx, $offy, string $driver, array $expected) : void
  588. {
  589. // Instance image
  590. $image = Image::factory(
  591. MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_crop.jpg',
  592. $driver
  593. );
  594. // Crop image and save it to a temp path, so we can verify height and width
  595. $result = $image->crop($width, $height, $offx, $offy);
  596. // Compare image dimensions to expected ones
  597. $this->assertSame(round($expected['width']), round($result->width));
  598. $this->assertSame(round($expected['height']), round($result->height));
  599. }
  600. /**
  601. * Data Provider for test_rotate
  602. *
  603. * @return array
  604. */
  605. public function provider_rotate() : array
  606. {
  607. // Init return array
  608. $return = [];
  609. // Setup return array
  610. foreach (static::$drivers as $driver)
  611. {
  612. // Rotate 360 degree
  613. $return[] = [
  614. 360,
  615. 100,
  616. 200,
  617. $driver
  618. ];
  619. // Rotate 450 (90) degree
  620. $return [] = [
  621. 450,
  622. 200,
  623. 100,
  624. $driver
  625. ];
  626. // Rotate -450 (-90) degree
  627. $return [] = [
  628. -450,
  629. 200,
  630. 100,
  631. $driver
  632. ];
  633. }
  634. return $return;
  635. }
  636. /**
  637. * Test for Image::rotate() method
  638. *
  639. * @dataProvider provider_rotate
  640. *
  641. * @param int $degree Degree to rotate
  642. * @param int $width Expected width
  643. * @param int $height Expected height
  644. * @param string $driver Driver to use
  645. *
  646. * @throws Image_Exception
  647. * @throws KO7_Exception
  648. */
  649. public function test_rotate(int $degree, int $width, int $height, string $driver) : void
  650. {
  651. // Load Image
  652. $image = Image::factory(
  653. MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_crop.jpg',
  654. $driver
  655. );
  656. // Rotate Image
  657. $result = $image->rotate($degree);
  658. // Assert width and height are as expected
  659. $this->assertSame(round($width), round($result->width));
  660. $this->assertSame(round($height), round($result->height));
  661. }
  662. /**
  663. * Data Provider for test_flip
  664. *
  665. * @return array
  666. */
  667. public function provider_flip() : array
  668. {
  669. // Init return array
  670. $return = [];
  671. // Setup return array
  672. foreach (static::$drivers as $driver)
  673. {
  674. // Flip Horizontal
  675. $return[] = [
  676. Image::HORIZONTAL,
  677. $driver
  678. ];
  679. // Flip Vertical
  680. $return[] = [
  681. Image::VERTICAL,
  682. $driver
  683. ];
  684. }
  685. return $return;
  686. }
  687. /**
  688. * Test for Image::flip() method.
  689. *
  690. * @dataProvider provider_flip
  691. *
  692. * @param int $direction Direction to Flip
  693. * @param string $driver Driver to use
  694. *
  695. * @throws Image_Exception
  696. * @throws KO7_Exception
  697. */
  698. public function test_flip(int $direction, string $driver) : void
  699. {
  700. // Load Image
  701. $image = Image::factory(
  702. MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_crop.jpg',
  703. $driver
  704. );
  705. // Flip it!
  706. $result = $image->flip($direction);
  707. // Assert it is still the same image
  708. $this->assertSame($image, $result);
  709. }
  710. /**
  711. * Data Provider for test_sharpen
  712. *
  713. * @return array
  714. */
  715. public function provider_sharpen() : array
  716. {
  717. // Init return array
  718. $return = [];
  719. // Setup return array
  720. foreach (static::$drivers as $driver)
  721. {
  722. // Test with valid integer
  723. $return[] = [
  724. 3,
  725. $driver
  726. ];
  727. // Test with to high integer
  728. $return[] = [
  729. 144,
  730. $driver
  731. ];
  732. }
  733. return $return;
  734. }
  735. /**
  736. * Test for Image::sharpen() method
  737. *
  738. * @dataProvider provider_sharpen
  739. *
  740. * @param int $amount Amount to sharpen
  741. * @param string $driver Driver to use
  742. *
  743. * @throws Image_Exception
  744. * @throws KO7_Exception
  745. */
  746. public function test_sharpen(int $amount, string $driver) : void
  747. {
  748. // Load Image
  749. $image = Image::factory(
  750. MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_crop.jpg',
  751. $driver
  752. );
  753. // Sharpen it!
  754. $result = $image->sharpen($amount);
  755. // Check if still same image
  756. $this->assertSame($image, $result);
  757. }
  758. /**
  759. * Data Provider for test_reflection
  760. *
  761. * @return array
  762. */
  763. public function provider_reflection() : array
  764. {
  765. // Init return array
  766. $return = [];
  767. // Setup return array
  768. foreach (static::$drivers as $driver)
  769. {
  770. // Test fade in
  771. $return[] = [
  772. 300,
  773. 50,
  774. TRUE,
  775. $driver
  776. ];
  777. // Test fade out
  778. $return[] = [
  779. 50,
  780. 200,
  781. FALSE,
  782. $driver
  783. ];
  784. }
  785. return $return;
  786. }
  787. /**
  788. * Test for Image::reflection() method
  789. *
  790. * @dataProvider provider_reflection
  791. *
  792. * @param int $height Height of reflection
  793. * @param int $opacity Opacity of reflection
  794. * @param bool $fade_in TRUE fad in, FALSE fade out
  795. * @param string $driver Driver to use
  796. *
  797. * @throws Image_Exception
  798. * @throws KO7_Exception
  799. */
  800. public function test_reflection(int $height, int $opacity, bool $fade_in, string $driver) : void
  801. {
  802. // Load Image
  803. $image = Image::factory(
  804. MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_crop.jpg',
  805. $driver
  806. );
  807. // Reflect it
  808. $result = $image->reflection($height, $opacity, $fade_in);
  809. // Assert still same Image
  810. $this->assertSame($image, $result);
  811. }
  812. /**
  813. * Data Provider for test_watermark
  814. *
  815. * @return array
  816. */
  817. public function provider_watermark() : array
  818. {
  819. // Init return array
  820. $return = [];
  821. // Setup return array
  822. foreach (static::$drivers as $driver)
  823. {
  824. // Test offset null
  825. $return[] = [
  826. NULL,
  827. NULL,
  828. 20,
  829. $driver
  830. ];
  831. // Test offset true
  832. $return[] = [
  833. TRUE,
  834. TRUE,
  835. 110,
  836. $driver
  837. ];
  838. // Test offset negative
  839. $return[] = [
  840. -10,
  841. -20,
  842. 20,
  843. $driver
  844. ];
  845. }
  846. return $return;
  847. }
  848. /**
  849. * Test for Image::watermark() mehtod
  850. *
  851. * @dataProvider provider_watermark
  852. *
  853. * @param mixed $offset_x Offset from the left
  854. * @param mixed $offset_y Offset from the right
  855. * @param int|null $opacity Opacity of watermark
  856. * @param string $driver Driver to use
  857. *
  858. * @throws Image_Exception
  859. * @throws KO7_Exception
  860. */
  861. public function test_watermark($offset_x, $offset_y, ?int $opacity, string $driver) : void
  862. {
  863. // Load Image
  864. $image = Image::factory(
  865. MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_image.jpg',
  866. $driver
  867. );
  868. // Load Watermark
  869. $image_watermark = Image::factory(
  870. MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'watermark.png',
  871. $driver
  872. );
  873. // Watermark our image
  874. $result = $image->watermark($image_watermark, $offset_x, $offset_y, $opacity);
  875. // Assert still same Image
  876. $this->assertSame($image, $result);
  877. }
  878. /**
  879. * Data Provider for test_background
  880. *
  881. * @return array
  882. */
  883. public function provider_background() : array
  884. {
  885. // Init return array
  886. $return = [];
  887. // Setup return array
  888. foreach (static::$drivers as $driver)
  889. {
  890. // Test with full hex
  891. $return[] = [
  892. '#e2e2e2',
  893. 20,
  894. $driver
  895. ];
  896. // Test with short hex
  897. $return[] = [
  898. '#bbb',
  899. 110,
  900. $driver
  901. ];
  902. // Test hex without #
  903. $return[] = [
  904. 'fff',
  905. 20,
  906. $driver
  907. ];
  908. }
  909. return $return;
  910. }
  911. /**
  912. * Test for Image::background() method.
  913. *
  914. * @dataProvider provider_background
  915. *
  916. * @param string $color Background color
  917. * @param int $opacity Opacity of background
  918. * @param string $driver Driver to use
  919. *
  920. * @throws Image_Exception
  921. * @throws KO7_Exception
  922. */
  923. public function test_background(string $color, int $opacity, string $driver) : void
  924. {
  925. // Load Image
  926. $image = Image::factory(
  927. MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.'test_image.jpg',
  928. $driver
  929. );
  930. // Apply Background
  931. $result = $image->background($color, $opacity);
  932. // Assert still same Image
  933. $this->assertSame($image, $result);
  934. }
  935. /**
  936. * Data Provider for test_render
  937. *
  938. * @return array
  939. */
  940. public function provider_render() : array
  941. {
  942. // Init return array
  943. $return = [];
  944. // Setup return array
  945. foreach (static::$drivers as $driver)
  946. {
  947. // Render gif as png
  948. $return[] = [
  949. 'test_image.gif',
  950. '.png',
  951. 100,
  952. $driver
  953. ];
  954. // Render png as jpg
  955. $return[] = [
  956. 'test_image.png',
  957. 'jpg',
  958. 20,
  959. $driver
  960. ];
  961. }
  962. return $return;
  963. }
  964. /**
  965. * Test for Image::render() method
  966. *
  967. * @dataProvider provider_render
  968. *
  969. * @param string $file
  970. * @param string $extension
  971. * @param int $quality
  972. * @param string $driver
  973. *
  974. * @throws Image_Exception
  975. * @throws KO7_Exception
  976. */
  977. public function test_render(string $file, string $extension, int $quality, string $driver) : void
  978. {
  979. // Load Image
  980. $image = Image::factory(
  981. MODPATH . 'image'.DIRECTORY_SEPARATOR.'tests'.DIRECTORY_SEPARATOR.'test_data'.DIRECTORY_SEPARATOR.$file,
  982. $driver
  983. );
  984. // Render Image
  985. $image->render($extension, $quality);
  986. // Simply assert no exception is thrown / true
  987. $this->assertTrue(TRUE);
  988. }
  989. }