ImageTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test;
  8. use OC;
  9. use OCP\IConfig;
  10. class ImageTest extends \Test\TestCase {
  11. public static function tearDownAfterClass(): void {
  12. @unlink(OC::$SERVERROOT.'/tests/data/testimage2.png');
  13. @unlink(OC::$SERVERROOT.'/tests/data/testimage2.jpg');
  14. parent::tearDownAfterClass();
  15. }
  16. public function testConstructDestruct() {
  17. $img = new \OC_Image();
  18. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  19. $this->assertInstanceOf('\OC_Image', $img);
  20. $this->assertInstanceOf('\OCP\IImage', $img);
  21. unset($img);
  22. $imgcreate = imagecreatefromjpeg(OC::$SERVERROOT.'/tests/data/testimage.jpg');
  23. $img = new \OC_Image();
  24. $img->setResource($imgcreate);
  25. $this->assertInstanceOf('\OC_Image', $img);
  26. $this->assertInstanceOf('\OCP\IImage', $img);
  27. unset($img);
  28. $base64 = base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif'));
  29. $img = new \OC_Image();
  30. $img->loadFromBase64($base64);
  31. $this->assertInstanceOf('\OC_Image', $img);
  32. $this->assertInstanceOf('\OCP\IImage', $img);
  33. unset($img);
  34. $img = new \OC_Image();
  35. $this->assertInstanceOf('\OC_Image', $img);
  36. $this->assertInstanceOf('\OCP\IImage', $img);
  37. unset($img);
  38. }
  39. public function testValid() {
  40. $img = new \OC_Image();
  41. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  42. $this->assertTrue($img->valid());
  43. $text = base64_encode("Lorem ipsum dolor sir amet …");
  44. $img = new \OC_Image();
  45. $img->loadFromBase64($text);
  46. $this->assertFalse($img->valid());
  47. $img = new \OC_Image();
  48. $this->assertFalse($img->valid());
  49. }
  50. public function testMimeType() {
  51. $img = new \OC_Image();
  52. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  53. $this->assertEquals('image/png', $img->mimeType());
  54. $img = new \OC_Image();
  55. $this->assertEquals('', $img->mimeType());
  56. $img = new \OC_Image();
  57. $img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
  58. $this->assertEquals('image/jpeg', $img->mimeType());
  59. $img = new \OC_Image();
  60. $img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
  61. $this->assertEquals('image/gif', $img->mimeType());
  62. }
  63. public function testWidth() {
  64. $img = new \OC_Image();
  65. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  66. $this->assertEquals(128, $img->width());
  67. $img = new \OC_Image();
  68. $img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
  69. $this->assertEquals(1680, $img->width());
  70. $img = new \OC_Image();
  71. $img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
  72. $this->assertEquals(64, $img->width());
  73. $img = new \OC_Image();
  74. $this->assertEquals(-1, $img->width());
  75. }
  76. public function testHeight() {
  77. $img = new \OC_Image();
  78. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  79. $this->assertEquals(128, $img->height());
  80. $img = new \OC_Image();
  81. $img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
  82. $this->assertEquals(1050, $img->height());
  83. $img = new \OC_Image();
  84. $img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
  85. $this->assertEquals(64, $img->height());
  86. $img = new \OC_Image();
  87. $this->assertEquals(-1, $img->height());
  88. }
  89. public function testSave() {
  90. $img = new \OC_Image();
  91. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  92. $img->resize(16);
  93. $img->save(OC::$SERVERROOT.'/tests/data/testimage2.png');
  94. $this->assertEquals(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage2.png'), $img->data());
  95. $img = new \OC_Image();
  96. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.jpg');
  97. $img->resize(128);
  98. $img->save(OC::$SERVERROOT.'/tests/data/testimage2.jpg');
  99. $this->assertEquals(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage2.jpg'), $img->data());
  100. }
  101. public function testData() {
  102. $img = new \OC_Image();
  103. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  104. $raw = imagecreatefromstring(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.png'));
  105. // Preserve transparency
  106. imagealphablending($raw, true);
  107. imagesavealpha($raw, true);
  108. ob_start();
  109. imagepng($raw);
  110. $expected = ob_get_clean();
  111. $this->assertEquals($expected, $img->data());
  112. $config = $this->createMock(IConfig::class);
  113. $config->expects($this->once())
  114. ->method('getAppValue')
  115. ->with('preview', 'jpeg_quality', '80')
  116. ->willReturn(null);
  117. $config->expects($this->once())
  118. ->method('getSystemValueInt')
  119. ->with('preview_max_memory', 256)
  120. ->willReturn(256);
  121. $img = new \OC_Image(null, null, $config);
  122. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.jpg');
  123. $raw = imagecreatefromstring(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
  124. imageinterlace($raw, true);
  125. ob_start();
  126. imagejpeg($raw, null, 80);
  127. $expected = ob_get_clean();
  128. $this->assertEquals($expected, $img->data());
  129. $img = new \OC_Image();
  130. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.gif');
  131. $raw = imagecreatefromstring(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif'));
  132. ob_start();
  133. imagegif($raw);
  134. $expected = ob_get_clean();
  135. $this->assertEquals($expected, $img->data());
  136. }
  137. public function testDataNoResource() {
  138. $img = new \OC_Image();
  139. $this->assertNull($img->data());
  140. }
  141. /**
  142. * @depends testData
  143. */
  144. public function testToString() {
  145. $img = new \OC_Image();
  146. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  147. $expected = base64_encode($img->data());
  148. $this->assertEquals($expected, (string)$img);
  149. $img = new \OC_Image();
  150. $img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
  151. $expected = base64_encode($img->data());
  152. $this->assertEquals($expected, (string)$img);
  153. $img = new \OC_Image();
  154. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.gif');
  155. $expected = base64_encode($img->data());
  156. $this->assertEquals($expected, (string)$img);
  157. }
  158. public function testResize() {
  159. $img = new \OC_Image();
  160. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  161. $this->assertTrue($img->resize(32));
  162. $this->assertEquals(32, $img->width());
  163. $this->assertEquals(32, $img->height());
  164. $img = new \OC_Image();
  165. $img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
  166. $this->assertTrue($img->resize(840));
  167. $this->assertEquals(840, $img->width());
  168. $this->assertEquals(525, $img->height());
  169. $img = new \OC_Image();
  170. $img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
  171. $this->assertTrue($img->resize(100));
  172. $this->assertEquals(100, $img->width());
  173. $this->assertEquals(100, $img->height());
  174. }
  175. public function testPreciseResize() {
  176. $img = new \OC_Image();
  177. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  178. $this->assertTrue($img->preciseResize(128, 512));
  179. $this->assertEquals(128, $img->width());
  180. $this->assertEquals(512, $img->height());
  181. $img = new \OC_Image();
  182. $img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
  183. $this->assertTrue($img->preciseResize(64, 840));
  184. $this->assertEquals(64, $img->width());
  185. $this->assertEquals(840, $img->height());
  186. $img = new \OC_Image();
  187. $img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
  188. $this->assertTrue($img->preciseResize(1000, 1337));
  189. $this->assertEquals(1000, $img->width());
  190. $this->assertEquals(1337, $img->height());
  191. }
  192. public function testCenterCrop() {
  193. $img = new \OC_Image();
  194. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  195. $img->centerCrop();
  196. $this->assertEquals(128, $img->width());
  197. $this->assertEquals(128, $img->height());
  198. $img = new \OC_Image();
  199. $img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
  200. $img->centerCrop();
  201. $this->assertEquals(1050, $img->width());
  202. $this->assertEquals(1050, $img->height());
  203. $img = new \OC_Image();
  204. $img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
  205. $img->centerCrop(512);
  206. $this->assertEquals(512, $img->width());
  207. $this->assertEquals(512, $img->height());
  208. }
  209. public function testCrop() {
  210. $img = new \OC_Image();
  211. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  212. $this->assertTrue($img->crop(0, 0, 50, 20));
  213. $this->assertEquals(50, $img->width());
  214. $this->assertEquals(20, $img->height());
  215. $img = new \OC_Image();
  216. $img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
  217. $this->assertTrue($img->crop(500, 700, 550, 300));
  218. $this->assertEquals(550, $img->width());
  219. $this->assertEquals(300, $img->height());
  220. $img = new \OC_Image();
  221. $img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
  222. $this->assertTrue($img->crop(10, 10, 15, 15));
  223. $this->assertEquals(15, $img->width());
  224. $this->assertEquals(15, $img->height());
  225. }
  226. public static function sampleProvider() {
  227. return [
  228. ['testimage.png', [200, 100], [100, 100]],
  229. ['testimage.jpg', [840, 840], [840, 525]],
  230. ['testimage.gif', [200, 250], [200, 200]]
  231. ];
  232. }
  233. /**
  234. * @dataProvider sampleProvider
  235. *
  236. * @param string $filename
  237. * @param int[] $asked
  238. * @param int[] $expected
  239. */
  240. public function testFitIn($filename, $asked, $expected) {
  241. $img = new \OC_Image();
  242. $img->loadFromFile(OC::$SERVERROOT . '/tests/data/' . $filename);
  243. $this->assertTrue($img->fitIn($asked[0], $asked[1]));
  244. $this->assertEquals($expected[0], $img->width());
  245. $this->assertEquals($expected[1], $img->height());
  246. }
  247. public static function sampleFilenamesProvider() {
  248. return [
  249. ['testimage.png'],
  250. ['testimage.jpg'],
  251. ['testimage.gif']
  252. ];
  253. }
  254. /**
  255. * Image should not be resized if it's already smaller than what is required
  256. *
  257. * @dataProvider sampleFilenamesProvider
  258. *
  259. * @param string $filename
  260. */
  261. public function testScaleDownToFitWhenSmallerAlready($filename) {
  262. $img = new \OC_Image();
  263. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/' . $filename);
  264. $currentWidth = $img->width();
  265. $currentHeight = $img->height();
  266. // We pick something larger than the image we want to scale down
  267. $this->assertFalse($img->scaleDownToFit(4000, 4000));
  268. // The dimensions of the image should not have changed since it's smaller already
  269. $resizedWidth = $img->width();
  270. $resizedHeight = $img->height();
  271. $this->assertEquals(
  272. $currentWidth, $img->width(), "currentWidth $currentWidth resizedWidth $resizedWidth \n"
  273. );
  274. $this->assertEquals(
  275. $currentHeight, $img->height(),
  276. "currentHeight $currentHeight resizedHeight $resizedHeight \n"
  277. );
  278. }
  279. public static function largeSampleProvider() {
  280. return [
  281. ['testimage.png', [200, 100], [100, 100]],
  282. ['testimage.jpg', [840, 840], [840, 525]],
  283. ];
  284. }
  285. /**
  286. * @dataProvider largeSampleProvider
  287. *
  288. * @param string $filename
  289. * @param int[] $asked
  290. * @param int[] $expected
  291. */
  292. public function testScaleDownWhenBigger($filename, $asked, $expected) {
  293. $img = new \OC_Image();
  294. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/' . $filename);
  295. //$this->assertTrue($img->scaleDownToFit($asked[0], $asked[1]));
  296. $img->scaleDownToFit($asked[0], $asked[1]);
  297. $this->assertEquals($expected[0], $img->width());
  298. $this->assertEquals($expected[1], $img->height());
  299. }
  300. public function convertDataProvider() {
  301. return [
  302. [ 'image/gif'],
  303. [ 'image/jpeg'],
  304. [ 'image/png'],
  305. ];
  306. }
  307. /**
  308. * @dataProvider convertDataProvider
  309. */
  310. public function testConvert($mimeType) {
  311. $img = new \OC_Image();
  312. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
  313. $tempFile = tempnam(sys_get_temp_dir(), 'img-test');
  314. $img->save($tempFile, $mimeType);
  315. $this->assertEquals($mimeType, image_type_to_mime_type(exif_imagetype($tempFile)));
  316. }
  317. public function testMemoryLimitFromFile() {
  318. $img = new \OC_Image();
  319. $img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage-badheader.jpg');
  320. $this->assertFalse($img->valid());
  321. }
  322. public function testMemoryLimitFromData() {
  323. $data = file_get_contents(OC::$SERVERROOT.'/tests/data/testimage-badheader.jpg');
  324. $img = new \OC_Image();
  325. $img->loadFromData($data);
  326. $this->assertFalse($img->valid());
  327. }
  328. }