Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
InterfaceTest.php
Go to the documentation of this file.
1 <?php
7 
11 class InterfaceTest extends \PHPUnit\Framework\TestCase
12 {
18  protected $_adapters = [
19  \Magento\Framework\Image\Adapter\AdapterInterface::ADAPTER_GD2,
20  \Magento\Framework\Image\Adapter\AdapterInterface::ADAPTER_IM,
21  ];
22 
29  protected function _prepareData($data)
30  {
31  $result = [];
32  foreach ($this->_adapters as $adapterType) {
33  foreach ($data as $row) {
34  $row[] = $adapterType;
35  $result[] = $row;
36  }
37  }
38 
39  return $result;
40  }
41 
47  protected function _getFixtureImageSize()
48  {
49  return [311, 162];
50  }
51 
59  protected function _compareColors($colorBefore, $colorAfter)
60  {
61  // get different epsilon for 8 bit (max value = 255) & 16 bit (max value = 65535) images (eps = 5%)
62  $eps = max($colorAfter) > 255 ? 3500 : 20;
63 
64  $result = true;
65  foreach ($colorAfter as $i => $v) {
66  if (abs($colorBefore[$i] - $v) > $eps) {
67  $result = false;
68  break;
69  }
70  }
71  return $result;
72  }
73 
80  protected function _getFixture($pattern)
81  {
82  $dir = dirname(__DIR__) . '/_files/';
83  $data = glob($dir . $pattern);
84 
85  if (!empty($data)) {
86  return $data[0];
87  }
88 
89  return null;
90  }
91 
99  protected function _isFormatSupported($image, $adapter)
100  {
101  $data = pathinfo($image);
102  $supportedTypes = $adapter->getSupportedFormats();
103  return $image && file_exists($image) && in_array(strtolower($data['extension']), $supportedTypes);
104  }
105 
113  protected function _getAdapter($adapterType)
114  {
115  try {
117  $adapter = $objectManager->get(\Magento\Framework\Image\AdapterFactory::class)->create($adapterType);
118  return $adapter;
119  } catch (\Exception $e) {
120  $this->markTestSkipped($e->getMessage());
121  }
122  }
123 
130  public function testCheckDependencies($adapterType)
131  {
132  $this->_getAdapter($adapterType);
133  }
134 
135  public function adaptersDataProvider()
136  {
137  return [
138  [\Magento\Framework\Image\Adapter\AdapterInterface::ADAPTER_GD2],
139  [\Magento\Framework\Image\Adapter\AdapterInterface::ADAPTER_IM]
140  ];
141  }
142 
150  public function testOpen($image, $adapterType)
151  {
152  $adapter = $this->_getAdapter($adapterType);
153  try {
154  $adapter->open($image);
155  } catch (\Exception $e) {
157  $this->assertFalse($result);
158  }
159  }
160 
161  public function openDataProvider()
162  {
163  return $this->_prepareData(
164  [
165  [null],
166  [$this->_getFixture('image_adapters_test.png')],
167  [$this->_getFixture('image_adapters_test.tiff')],
168  [$this->_getFixture('image_adapters_test.bmp')],
169  ]
170  );
171  }
172 
177  public function testGetImage($adapterType)
178  {
179  $adapter = $this->_getAdapter($adapterType);
180  $adapter->open($this->_getFixture('image_adapters_test.png'));
181  $this->assertNotEmpty($adapter->getImage());
182  }
183 
191  public function testImageSize($image, $adapterType)
192  {
193  $adapter = $this->_getAdapter($adapterType);
194  try {
195  $adapter->open($image);
196  $this->assertEquals(
197  $this->_getFixtureImageSize(),
198  [$adapter->getOriginalWidth(), $adapter->getOriginalHeight()]
199  );
200  } catch (\Exception $e) {
202  $this->assertFalse($result);
203  }
204  }
205 
214  public function testSave($image, $tempPath, $adapterType)
215  {
216  $adapter = $this->_getAdapter($adapterType);
217  $adapter->open($image);
218  try {
219  call_user_func_array([$adapter, 'save'], $tempPath);
220  $tempPath = join('', $tempPath);
221  $this->assertFileExists($tempPath);
222  unlink($tempPath);
223  } catch (\Exception $e) {
224  $this->assertFalse(is_dir($tempPath[0]) && is_writable($tempPath[0]));
225  }
226  }
227 
228  public function saveDataProvider()
229  {
230  $dir = \Magento\TestFramework\Helper\Bootstrap::getInstance()->getAppTempDir() . '/';
231  return $this->_prepareData(
232  [
233  [$this->_getFixture('image_adapters_test.png'), [$dir . uniqid('test_image_adapter')]],
234  [$this->_getFixture('image_adapters_test.png'), [$dir, uniqid('test_image_adapter')]],
235  ]
236  );
237  }
238 
247  public function testResize($image, $dims, $adapterType)
248  {
249  $adapter = $this->_getAdapter($adapterType);
250  $adapter->open($image);
251  try {
252  $adapter->resize($dims[0], $dims[1]);
253  $this->assertEquals($dims, [$adapter->getOriginalWidth(), $adapter->getOriginalHeight()]);
254  } catch (\Exception $e) {
255  $result = $dims[0] !== null && $dims[0] <= 0 ||
256  $dims[1] !== null && $dims[1] <= 0 ||
257  empty(${$dims[0]}) && empty(${$dims[1]});
258  $this->assertTrue($result);
259  }
260  }
261 
262  public function resizeDataProvider()
263  {
264  return $this->_prepareData(
265  [
266  [$this->_getFixture('image_adapters_test.png'), [150, 70]],
267  [$this->_getFixture('image_adapters_test.png'), [null, 70]],
268  [$this->_getFixture('image_adapters_test.png'), [100, null]],
269  [$this->_getFixture('image_adapters_test.png'), [null, null]],
270  [$this->_getFixture('image_adapters_test.png'), [-100, -50]],
271  ]
272  );
273  }
274 
284  public function testRotate($image, $angle, $pixel, $adapterType)
285  {
286  $adapter = $this->_getAdapter($adapterType);
287  $adapter->open($image);
288 
289  $size = [$adapter->getOriginalWidth(), $adapter->getOriginalHeight()];
290 
291  $colorBefore = $adapter->getColorAt($pixel['x'], $pixel['y']);
292  $adapter->rotate($angle);
293 
294  $newPixel = $this->_convertCoordinates(
295  $pixel,
296  $angle,
297  $size,
298  [$adapter->getOriginalWidth(), $adapter->getOriginalHeight()]
299  );
300  $colorAfter = $adapter->getColorAt($newPixel['x'], $newPixel['y']);
301 
302  $result = $this->_compareColors($colorBefore, $colorAfter);
303  $this->assertTrue($result, join(',', $colorBefore) . ' not equals ' . join(',', $colorAfter));
304  }
305 
315  protected function _convertCoordinates($pixel, $angle, $oldSize, $size)
316  {
317  $angle = $angle * pi() / 180;
318  $center = ['x' => $oldSize[0] / 2, 'y' => $oldSize[1] / 2];
319 
320  $pixel['x'] -= $center['x'];
321  $pixel['y'] -= $center['y'];
322  return [
323  'x' => round($size[0] / 2 + $pixel['x'] * cos($angle) + $pixel['y'] * sin($angle), 0),
324  'y' => round($size[1] / 2 + $pixel['y'] * cos($angle) - $pixel['x'] * sin($angle), 0),
325  ];
326  }
327 
328  public function rotateDataProvider()
329  {
330  return $this->_prepareData(
331  [
332  [$this->_getFixture('image_adapters_test.png'), 45, ['x' => 157, 'y' => 35]],
333  [$this->_getFixture('image_adapters_test.png'), 48, ['x' => 157, 'y' => 35]],
334  [$this->_getFixture('image_adapters_test.png'), 90, ['x' => 250, 'y' => 74]],
335  [$this->_getFixture('image_adapters_test.png'), 180, ['x' => 250, 'y' => 74]],
336  ]
337  );
338  }
339 
355  $image,
356  $watermark,
357  $alphaPercentage,
358  $comparePoint1,
359  $comparePoint2,
360  $adapterType
361  ) {
362  $imageAdapter = $this->_getAdapter($adapterType);
363  $imageAdapter->open($image);
364 
365  $watermarkAdapter = $this->_getAdapter($adapterType);
366  $watermarkAdapter->open($watermark);
367 
368  list($comparePoint1X, $comparePoint1Y) = $comparePoint1;
369  list($comparePoint2X, $comparePoint2Y) = $comparePoint2;
370 
371  $imageAdapter
372  ->setWatermarkImageOpacity($alphaPercentage)
373  ->setWatermarkPosition(\Magento\Framework\Image\Adapter\AbstractAdapter::POSITION_TOP_LEFT)
374  ->watermark($watermark);
375 
376  $comparePoint1Color = $imageAdapter->getColorAt($comparePoint1X, $comparePoint1Y);
377  unset($comparePoint1Color['alpha']);
378 
379  $comparePoint2Color = $imageAdapter->getColorAt($comparePoint2X, $comparePoint2Y);
380  unset($comparePoint2Color['alpha']);
381 
382  $result = $this->_compareColors($comparePoint1Color, $comparePoint2Color);
383  $message = sprintf(
384  '%s should be different to %s due to alpha transparency',
385  join(',', $comparePoint1Color),
386  join(',', $comparePoint2Color)
387  );
388  $this->assertFalse($result, $message);
389  }
390 
392  {
393  return $this->_prepareData(
394  [
395  // Watermark with alpha channel, 25%
396  [
397  $this->_getFixture('watermark_alpha_base_image.jpg'),
398  $this->_getFixture('watermark_alpha.png'),
399  25,
400  [ 23, 3 ],
401  [ 23, 30 ]
402  ],
403  // Watermark with alpha channel, 50%
404  [
405  $this->_getFixture('watermark_alpha_base_image.jpg'),
406  $this->_getFixture('watermark_alpha.png'),
407  50,
408  [ 23, 3 ],
409  [ 23, 30 ]
410  ],
411  // Watermark with no alpha channel, 50%
412  [
413  $this->_getFixture('watermark_alpha_base_image.jpg'),
414  $this->_getFixture('watermark.png'),
415  50,
416  [ 3, 3 ],
417  [ 23,3 ]
418  ],
419  // Watermark with no alpha channel, 100%
420  [
421  $this->_getFixture('watermark_alpha_base_image.jpg'),
422  $this->_getFixture('watermark.png'),
423  100,
424  [ 3, 3 ],
425  [ 3, 60 ]
426  ],
427  ]
428  );
429  }
430 
447  public function testWatermarkPosition(
448  $image,
449  $watermark,
450  $width,
451  $height,
452  $opacity,
453  $position,
454  $colorX,
455  $colorY,
456  $adapterType
457  ) {
458  $adapter = $this->_getAdapter($adapterType);
459  $adapter->open($image);
460  $pixel = $this->_prepareColor(['x' => $colorX, 'y' => $colorY], $position, $adapter);
461 
462  $colorBefore = $adapter->getColorAt($pixel['x'], $pixel['y']);
463  $adapter->setWatermarkWidth(
464  $width
465  )->setWatermarkHeight(
466  $height
467  )->setWatermarkImageOpacity(
468  $opacity
469  )->setWatermarkPosition(
470  $position
471  )->watermark(
472  $watermark
473  );
474  $colorAfter = $adapter->getColorAt($pixel['x'], $pixel['y']);
475 
476  $result = $this->_compareColors($colorBefore, $colorAfter);
477  $message = join(',', $colorBefore) . ' not equals ' . join(',', $colorAfter);
478  $this->assertFalse($result, $message);
479  }
480 
482  {
483  return $this->_prepareData(
484  [
485  [
486  $this->_getFixture('image_adapters_test.png'),
487  $this->_getFixture('watermark.png'),
488  50,
489  50,
490  100,
492  10,
493  10,
494  ],
495  [
496  $this->_getFixture('image_adapters_test.png'),
497  $this->_getFixture('watermark.png'),
498  100,
499  70,
500  100,
502  10,
503  10
504  ],
505  [
506  $this->_getFixture('image_adapters_test.png'),
507  $this->_getFixture('watermark.png'),
508  100,
509  70,
510  100,
512  10,
513  10
514  ],
515  [
516  $this->_getFixture('image_adapters_test.png'),
517  $this->_getFixture('watermark.png'),
518  100,
519  100,
520  100,
522  10,
523  10
524  ],
525  [
526  $this->_getFixture('image_adapters_test.png'),
527  $this->_getFixture('watermark.jpg'),
528  50,
529  50,
530  100,
532  10,
533  10
534  ],
535  [
536  $this->_getFixture('image_adapters_test.png'),
537  $this->_getFixture('watermark.gif'),
538  50,
539  50,
540  100,
542  10,
543  10
544  ],
545  ]
546  );
547  }
548 
557  protected function _prepareColor($pixel, $position, $adapter)
558  {
559  switch ($position) {
560  case \Magento\Framework\Image\Adapter\AbstractAdapter::POSITION_BOTTOM_RIGHT:
561  $pixel['x'] = $adapter->getOriginalWidth() - 1;
562  $pixel['y'] = $adapter->getOriginalHeight() - 1;
563  break;
564  case \Magento\Framework\Image\Adapter\AbstractAdapter::POSITION_BOTTOM_LEFT:
565  $pixel['x'] = 1;
566  $pixel['y'] = $adapter->getOriginalHeight() - 1;
567  break;
568  case \Magento\Framework\Image\Adapter\AbstractAdapter::POSITION_TOP_LEFT:
569  $pixel['x'] = 1;
570  $pixel['y'] = 1;
571  break;
572  case \Magento\Framework\Image\Adapter\AbstractAdapter::POSITION_TOP_RIGHT:
573  $pixel['x'] = $adapter->getOriginalWidth() - 1;
574  $pixel['y'] = 1;
575  break;
576  case \Magento\Framework\Image\Adapter\AbstractAdapter::POSITION_CENTER:
577  $pixel['x'] = $adapter->getOriginalWidth() / 2;
578  $pixel['y'] = $adapter->getOriginalHeight() / 2;
579  break;
580  case \Magento\Framework\Image\Adapter\AbstractAdapter::POSITION_STRETCH:
581  case \Magento\Framework\Image\Adapter\AbstractAdapter::POSITION_TILE:
582  $pixel['x'] = round($adapter->getOriginalWidth() / 3);
583  $pixel['y'] = round($adapter->getOriginalHeight() / 3);
584  break;
585  }
586  return $pixel;
587  }
588 
600  public function testCrop($image, $left, $top, $right, $bottom, $adapterType)
601  {
602  $adapter = $this->_getAdapter($adapterType);
603  $adapter->open($image);
604 
605  $expectedSize = [
606  $adapter->getOriginalWidth() - $left - $right,
607  $adapter->getOriginalHeight() - $top - $bottom,
608  ];
609 
610  $adapter->crop($top, $left, $right, $bottom);
611 
612  $newSize = [$adapter->getOriginalWidth(), $adapter->getOriginalHeight()];
613 
614  $this->assertEquals($expectedSize, $newSize);
615  }
616 
617  public function cropDataProvider()
618  {
619  return $this->_prepareData(
620  [
621  [$this->_getFixture('image_adapters_test.png'), 50, 50, 75, 75],
622  [$this->_getFixture('image_adapters_test.png'), 20, 50, 35, 35],
623  [$this->_getFixture('image_adapters_test.png'), 0, 0, 0, 0],
624  ]
625  );
626  }
627 
637  public function testCreatePngFromString($pixel1, $expectedColor1, $pixel2, $expectedColor2, $adapterType)
638  {
639  $adapter = $this->_getAdapter($adapterType);
640 
643  \Magento\Framework\Filesystem\Directory\ReadFactory::class
644  );
645  $reader = $readFactory->create(BP);
646  $path = $reader->getAbsolutePath('lib/internal/LinLibertineFont/LinLibertine_Re-4.4.1.ttf');
647  $adapter->createPngFromString('T', $path);
648  $adapter->refreshImageDimensions();
649 
650  $color1 = $adapter->getColorAt($pixel1['x'], $pixel1['y']);
651  unset($color1['alpha']);
652  $this->assertEquals($expectedColor1, $color1);
653 
654  $color2 = $adapter->getColorAt($pixel2['x'], $pixel2['y']);
655  unset($color2['alpha']);
656  $this->assertEquals($expectedColor2, $color2);
657  }
658 
665  {
666  return [
667  [
668  ['x' => 5, 'y' => 8],
669  'expectedColor1' => ['red' => 0, 'green' => 0, 'blue' => 0],
670  ['x' => 0, 'y' => 14],
671  'expectedColor2' => ['red' => 255, 'green' => 255, 'blue' => 255],
672  \Magento\Framework\Image\Adapter\AdapterInterface::ADAPTER_GD2,
673  ],
674  [
675  ['x' => 5, 'y' => 12],
676  'expectedColor1' => ['red' => 0, 'green' => 0, 'blue' => 0],
677  ['x' => 0, 'y' => 20],
678  'expectedColor2' => ['red' => 255, 'green' => 255, 'blue' => 255],
679  \Magento\Framework\Image\Adapter\AdapterInterface::ADAPTER_IM
680  ],
681  [
682  ['x' => 1, 'y' => 14],
683  'expectedColor1' => ['red' => 255, 'green' => 255, 'blue' => 255],
684  ['x' => 5, 'y' => 12],
685  'expectedColor2' => ['red' => 0, 'green' => 0, 'blue' => 0],
686  \Magento\Framework\Image\Adapter\AdapterInterface::ADAPTER_GD2
687  ],
688  [
689  ['x' => 1, 'y' => 20],
690  'expectedColor1' => ['red' => 255, 'green' => 255, 'blue' => 255],
691  ['x' => 5, 'y' => 16],
692  'expectedColor2' => ['red' => 0, 'green' => 0, 'blue' => 0],
693  \Magento\Framework\Image\Adapter\AdapterInterface::ADAPTER_IM
694  ]
695  ];
696  }
697 
698  public function testValidateUploadFile()
699  {
701  $imageAdapter = $objectManager->get(\Magento\Framework\Image\AdapterFactory::class)->create();
702  $this->assertTrue($imageAdapter->validateUploadFile($this->_getFixture('magento_thumbnail.jpg')));
703  }
704 
709  {
711  $imageAdapter = $objectManager->get(\Magento\Framework\Image\AdapterFactory::class)->create();
712  $imageAdapter->validateUploadFile(__FILE__);
713  }
714 }
$objectManager
Definition: bootstrap.php:17
testCrop($image, $left, $top, $right, $bottom, $adapterType)
$pattern
Definition: website.php:22
defined('TESTS_BP')||define('TESTS_BP' __DIR__
Definition: _bootstrap.php:60
defined('MTF_BOOT_FILE')||define('MTF_BOOT_FILE' __FILE__
Definition: bootstrap.php:7
testWatermarkPosition( $image, $watermark, $width, $height, $opacity, $position, $colorX, $colorY, $adapterType)
$message
$adapter
Definition: webapi_user.php:16
testRotate($image, $angle, $pixel, $adapterType)
is_writable($path)
Definition: io.php:25
const BP
Definition: autoload.php:14
$i
Definition: gallery.phtml:31
testWatermarkWithAlphaTransparency( $image, $watermark, $alphaPercentage, $comparePoint1, $comparePoint2, $adapterType)
_convertCoordinates($pixel, $angle, $oldSize, $size)