ImageTest.php 12 KB

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