Completed
Pull Request — master (#19)
by Chad
03:44 queued 02:27
created

ImageTest::resizeOrientation()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 35
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 24
nc 2
nop 0
1
<?php
2
3
namespace TraderInteractive\Util;
4
5
use PHPUnit\Framework\TestCase;
6
7
/**
8
 * @coversDefaultClass \TraderInteractive\Util\Image
9
 */
10
final class ImageTest extends TestCase
11
{
12
    private $_sourceFilesDir;
13
    private $_tempDir;
14
15
    public function setUp()
16
    {
17
        $this->_sourceFilesDir = __DIR__ . '/_files';
18
        $this->_tempDir = sys_get_temp_dir() . '/imageUtilTest';
19
        if (is_dir($this->_tempDir)) {
20
            foreach (glob("{$this->_tempDir}/*") as $file) {
21
                unlink($file);
22
            }
23
24
            rmdir($this->_tempDir);
25
        }
26
    }
27
28
    /**
29
     * Downsize ratio 2.0 to 0.25
30
     *
31
     * @test
32
     * @covers ::resize
33
     * @covers ::resizeMulti
34
     */
35
    public function resizeDownsizeToMoreVerticalAspect()
36
    {
37
        $source = new \Imagick('pattern:gray0');
38
        $source->scaleImage(100, 50);
39
40
        $imagick = Image::resize($source, 10, 40, ['color' => 'white', 'maxWidth' => 10000, 'maxHeight' => 10000]);
41
42
        //making sure source didnt resize
43
        $this->assertSame(100, $source->getImageWidth());
44
        $this->assertSame(50, $source->getImageHeight());
45
46
        $this->assertSame(10, $imagick->getImageWidth());
47
        $this->assertSame(40, $imagick->getImageHeight());
48
49
        $whiteBarTop = $imagick->getImagePixelColor(4, 16)->getHsl();
50
        $whiteBarBottom = $imagick->getImagePixelColor(4, 22)->getHsl();
51
52
        $imageLeft = $imagick->getImagePixelColor(0, 19)->getHsl();
53
        $imageRight = $imagick->getImagePixelColor(9, 19)->getHsl();
54
        $imageTop = $imagick->getImagePixelColor(4, 17)->getHsl();
55
        $imageBottom = $imagick->getImagePixelColor(4, 21)->getHsl();
56
57
        $this->assertGreaterThan(0.9, $whiteBarTop['luminosity']);
58
        $this->assertGreaterThan(0.9, $whiteBarBottom['luminosity']);
59
60
        $this->assertLessThan(0.1, $imageLeft['luminosity']);
61
        $this->assertLessThan(0.1, $imageRight['luminosity']);
62
        $this->assertLessThan(0.1, $imageTop['luminosity']);
63
        $this->assertLessThan(0.1, $imageBottom['luminosity']);
64
    }
65
66
    /**
67
     * Downsize ratio 2.0 to 4.0
68
     *
69
     * @test
70
     * @covers ::resize
71
     * @covers ::resizeMulti
72
     */
73 View Code Duplication
    public function resizeDownsizeToMoreHorizontalAspect()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
74
    {
75
        $source = new \Imagick('pattern:gray0');
76
        $source->scaleImage(100, 50);
77
78
        $imagick = Image::resize($source, 40, 10);
79
80
        //making sure source didnt resize
81
        $this->assertSame(100, $source->getImageWidth());
82
        $this->assertSame(50, $source->getImageHeight());
83
84
        $this->assertSame(40, $imagick->getImageWidth());
85
        $this->assertSame(10, $imagick->getImageHeight());
86
87
        $whiteBarLeft = $imagick->getImagePixelColor(9, 4)->getHsl();
88
        $whiteBarRight = $imagick->getImagePixelColor(30, 4)->getHsl();
89
90
        $imageLeft = $imagick->getImagePixelColor(10, 4)->getHsl();
91
        $imageRight = $imagick->getImagePixelColor(29, 4)->getHsl();
92
        $imageTop = $imagick->getImagePixelColor(19, 0)->getHsl();
93
        $imageBottom = $imagick->getImagePixelColor(19, 9)->getHsl();
94
95
        $this->assertGreaterThan(0.9, $whiteBarLeft['luminosity']);
96
        $this->assertGreaterThan(0.9, $whiteBarRight['luminosity']);
97
98
        $this->assertLessThan(0.1, $imageLeft['luminosity']);
99
        $this->assertLessThan(0.1, $imageRight['luminosity']);
100
        $this->assertLessThan(0.1, $imageTop['luminosity']);
101
        $this->assertLessThan(0.1, $imageBottom['luminosity']);
102
    }
103
104
    /**
105
     * Upsize ratio 2.0 to 4.0
106
     *
107
     * @test
108
     * @covers ::resize
109
     * @covers ::resizeMulti
110
     */
111 View Code Duplication
    public function resizeUpsizeToMoreHorizontalAspectWithoutGrow()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
112
    {
113
        $source = new \Imagick('pattern:gray0');
114
        $source->scaleImage(100, 50);
115
116
        $imagick = Image::resize($source, 400, 100);
117
118
        //making sure source didnt resize
119
        $this->assertSame(100, $source->getImageWidth());
120
        $this->assertSame(50, $source->getImageHeight());
121
122
        $this->assertSame(400, $imagick->getImageWidth());
123
        $this->assertSame(100, $imagick->getImageHeight());
124
125
        $whiteBarLeft = $imagick->getImagePixelColor(99, 49)->getHsl();
126
        $whiteBarRight = $imagick->getImagePixelColor(300, 49)->getHsl();
127
128
        $imageTop = $imagick->getImagePixelColor(200, 26)->getHsl();
129
        $imageBottom = $imagick->getImagePixelColor(200, 74)->getHsl();
130
        $imageLeft = $imagick->getImagePixelColor(151, 50)->getHsl();
131
        $imageRight = $imagick->getImagePixelColor(249, 50)->getHsl();
132
133
        $this->assertGreaterThan(0.9, $whiteBarLeft['luminosity']);
134
        $this->assertGreaterThan(0.9, $whiteBarRight['luminosity']);
135
136
        $this->assertLessThan(0.1, $imageLeft['luminosity']);
137
        $this->assertLessThan(0.1, $imageRight['luminosity']);
138
        $this->assertLessThan(0.1, $imageTop['luminosity']);
139
        $this->assertLessThan(0.1, $imageBottom['luminosity']);
140
    }
141
142
    /**
143
     * Upsize ratio 2.0 to 4.0
144
     *
145
     * @test
146
     * @covers ::resize
147
     * @covers ::resizeMulti
148
     */
149 View Code Duplication
    public function resizeUpsizeToMoreHorizontalAspectWithGrow()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
150
    {
151
        $source = new \Imagick('pattern:gray0');
152
        $source->scaleImage(100, 50);
153
154
        $imagick = Image::resize($source, 400, 100, ['upsize' => true]);
155
156
        //making sure source didnt resize
157
        $this->assertSame(100, $source->getImageWidth());
158
        $this->assertSame(50, $source->getImageHeight());
159
160
        $this->assertSame(400, $imagick->getImageWidth());
161
        $this->assertSame(100, $imagick->getImageHeight());
162
163
        $whiteBarLeft = $imagick->getImagePixelColor(99, 49)->getHsl();
164
        $whiteBarRight = $imagick->getImagePixelColor(300, 49)->getHsl();
165
166
        $imageTop = $imagick->getImagePixelColor(249, 0)->getHsl();
167
        $imageBottom = $imagick->getImagePixelColor(249, 99)->getHsl();
168
        $imageLeft = $imagick->getImagePixelColor(100, 49)->getHsl();
169
        $imageRight = $imagick->getImagePixelColor(299, 49)->getHsl();
170
171
        $this->assertGreaterThan(0.9, $whiteBarLeft['luminosity']);
172
        $this->assertGreaterThan(0.9, $whiteBarRight['luminosity']);
173
174
        $this->assertLessThan(0.1, $imageLeft['luminosity']);
175
        $this->assertLessThan(0.1, $imageRight['luminosity']);
176
        $this->assertLessThan(0.1, $imageTop['luminosity']);
177
        $this->assertLessThan(0.1, $imageBottom['luminosity']);
178
    }
179
180
    /**
181
     * Upsize ratio 2.0 to 4.0
182
     *
183
     * @test
184
     * @covers ::resize
185
     * @covers ::resizeMulti
186
     */
187 View Code Duplication
    public function resizeUpsizeToMoreVerticalAspect()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
188
    {
189
        $source = new \Imagick('pattern:gray0');
190
        $source->scaleImage(100, 50);
191
192
        $imagick = Image::resize($source, 200, 400);
193
194
        //making sure source didnt resize
195
        $this->assertSame(100, $source->getImageWidth());
196
        $this->assertSame(50, $source->getImageHeight());
197
198
        $this->assertSame(200, $imagick->getImageWidth());
199
        $this->assertSame(400, $imagick->getImageHeight());
200
201
        $whiteBarLeft = $imagick->getImagePixelColor(49, 200)->getHsl();
202
        $whiteBarRight = $imagick->getImagePixelColor(151, 200)->getHsl();
203
204
        $imageTop = $imagick->getImagePixelColor(100, 176)->getHsl();
205
        $imageBottom = $imagick->getImagePixelColor(100, 224)->getHsl();
206
        $imageLeft = $imagick->getImagePixelColor(51, 200)->getHsl();
207
        $imageRight = $imagick->getImagePixelColor(149, 200)->getHsl();
208
209
        $this->assertGreaterThan(0.9, $whiteBarLeft['luminosity']);
210
        $this->assertGreaterThan(0.9, $whiteBarRight['luminosity']);
211
212
        $this->assertLessThan(0.1, $imageLeft['luminosity']);
213
        $this->assertLessThan(0.1, $imageRight['luminosity']);
214
        $this->assertLessThan(0.1, $imageTop['luminosity']);
215
        $this->assertLessThan(0.1, $imageBottom['luminosity']);
216
    }
217
218
    /**
219
     * @test
220
     * @covers ::resize
221
     * @covers ::resizeMulti
222
     * @expectedException \InvalidArgumentException
223
     * @expectedExceptionMessage a $boxSizes width was not between 0 and $options["maxWidth"]
224
     */
225
    public function resizeZeroBoxWidth()
226
    {
227
        Image::resize(new \Imagick(), 0, 10);
228
    }
229
230
    /**
231
     * @test
232
     * @covers ::resize
233
     * @covers ::resizeMulti
234
     * @expectedException \InvalidArgumentException
235
     * @expectedExceptionMessage a $boxSizes width was not between 0 and $options["maxWidth"]
236
     */
237
    public function resizeLargeBoxWidth()
238
    {
239
        Image::resize(new \Imagick(), 10001, 10, ['maxWidth' => 10000]);
240
    }
241
242
    /**
243
     * @test
244
     * @covers ::resize
245
     * @covers ::resizeMulti
246
     * @expectedException \InvalidArgumentException
247
     * @expectedExceptionMessage a $boxSizes height was not between 0 and $options["maxHeight"]
248
     */
249
    public function resizeZeroBoxHeight()
250
    {
251
        Image::resize(new \Imagick(), 10, 0);
252
    }
253
254
    /**
255
     * @test
256
     * @covers ::resize
257
     * @covers ::resizeMulti
258
     * @expectedException \InvalidArgumentException
259
     * @expectedExceptionMessage a $boxSizes height was not between 0 and $options["maxHeight"]
260
     */
261
    public function resizeLargeBoxHeight()
262
    {
263
        Image::resize(new \Imagick(), 10, 10001, ['maxHeight' => 10000]);
264
    }
265
266
    /**
267
     * @test
268
     * @covers ::resize
269
     * @covers ::resizeMulti
270
     * @expectedException \InvalidArgumentException
271
     * @expectedExceptionMessage $options["color"] was not a string
272
     */
273
    public function resizeNonStringColor()
274
    {
275
        Image::resize(new \Imagick(), 10, 10, ['color' => 0]);
276
    }
277
278
    /**
279
     * @test
280
     * @covers ::resize
281
     * @covers ::resizeMulti
282
     * @expectedException \InvalidArgumentException
283
     * @expectedExceptionMessage $options["maxWidth"] was not an int
284
     */
285
    public function resizeonIntMaxWidth()
286
    {
287
        Image::resize(new \Imagick(), 10, 10, ['maxWidth' => 'not int']);
288
    }
289
290
    /**
291
     * @test
292
     * @covers ::resize
293
     * @covers ::resizeMulti
294
     * @expectedException \InvalidArgumentException
295
     * @expectedExceptionMessage $options["maxHeight"] was not an int
296
     */
297
    public function resizeNonIntMaxHeight()
298
    {
299
        Image::resize(new \Imagick(), 10, 10, ['maxHeight' => 'not int']);
300
    }
301
302
    /**
303
     * @test
304
     * @covers ::resize
305
     * @covers ::resizeMulti
306
     * @expectedException \InvalidArgumentException
307
     * @expectedExceptionMessage $options["upsize"] was not a bool
308
     */
309
    public function resizeNonBoolUpsize()
310
    {
311
        Image::resize(new \Imagick(), 10, 10, ['upsize' => 'not bool']);
312
    }
313
314
    /**
315
     * Verify images are rotated according to EXIF header
316
     * @test
317
     * @covers ::resize
318
     * @covers ::resizeMulti
319
     */
320
    public function resizeOrientation()
321
    {
322
        $files = [
323
            "{$this->_sourceFilesDir}/bottom-right.jpg",
324
            "{$this->_sourceFilesDir}/left-bottom.jpg",
325
            "{$this->_sourceFilesDir}/right-top.jpg",
326
            "{$this->_sourceFilesDir}/top-left.jpg",
327
        ];
328
329
        $imageResults = [];
330
331
        foreach ($files as $file) {
332
            $source = new \Imagick($file);
333
            $imageWidth = $source->getimagewidth();
334
            $imageHeight = $source->getimageheight();
335
            $imageResults[] = Image::resize($source, $imageWidth, $imageHeight, []);
336
        }
337
338
        $this->assertSame(
339
            ['r' => 254, 'g' => 0, 'b' => 0, 'a' => 1],
340
            $imageResults[0]->getImagePixelColor(0, 0)->getColor()
341
        );
342
        $this->assertSame(
343
            ['r' => 0, 'g' => 0, 'b' => 0, 'a' => 1],
344
            $imageResults[1]->getImagePixelColor(0, 0)->getColor()
345
        );
346
        $this->assertSame(
347
            ['r' => 0, 'g' => 255, 'b' => 1, 'a' => 1],
348
            $imageResults[2]->getImagePixelColor(0, 0)->getColor()
349
        );
350
        $this->assertSame(
351
            ['r' => 0, 'g' => 0, 'b' => 254, 'a' => 1],
352
            $imageResults[3]->getImagePixelColor(0, 0)->getColor()
353
        );
354
    }
355
356
    /**
357
     * Downsize ratio 2.0 to 0.25 and 2.0 to 4.0
358
     *
359
     * @test
360
     * @covers ::resizeMulti
361
     */
362
    public function resizeMultiDownsizeToMoreVerticalAndMoreHorizontalAspect()
363
    {
364
        $source = new \Imagick('pattern:gray0');
365
        $source->scaleImage(100, 50);
366
367
        $results = Image::resizeMulti($source, [['width' => 10, 'height' => 40], ['width' => 40, 'height' => 10]]);
368
        $imagickOne = $results[0];
369
        $imagickTwo = $results[1];
370
371
        //making sure source didnt resize
372
        $this->assertSame(100, $source->getImageWidth());
373
        $this->assertSame(50, $source->getImageHeight());
374
375
        //check $imagick1
376
377
        $this->assertSame(10, $imagickOne->getImageWidth());
378
        $this->assertSame(40, $imagickOne->getImageHeight());
379
380
        $oneWhiteBarTop = $imagickOne->getImagePixelColor(4, 16)->getHsl();
381
        $oneWhiteBarBottom = $imagickOne->getImagePixelColor(4, 22)->getHsl();
382
383
        $oneImageLeft = $imagickOne->getImagePixelColor(0, 19)->getHsl();
384
        $oneImageRight = $imagickOne->getImagePixelColor(9, 19)->getHsl();
385
        $oneImageTop = $imagickOne->getImagePixelColor(4, 17)->getHsl();
386
        $oneImageBottom = $imagickOne->getImagePixelColor(4, 21)->getHsl();
387
388
        $this->assertGreaterThan(0.9, $oneWhiteBarTop['luminosity']);
389
        $this->assertGreaterThan(0.9, $oneWhiteBarBottom['luminosity']);
390
391
        $this->assertLessThan(0.1, $oneImageLeft['luminosity']);
392
        $this->assertLessThan(0.1, $oneImageRight['luminosity']);
393
        $this->assertLessThan(0.1, $oneImageTop['luminosity']);
394
        $this->assertLessThan(0.1, $oneImageBottom['luminosity']);
395
396
        //check $imagick2
397
398
        $this->assertSame(40, $imagickTwo->getImageWidth());
399
        $this->assertSame(10, $imagickTwo->getImageHeight());
400
401
        $twoWhiteBarLeft = $imagickTwo->getImagePixelColor(9, 4)->getHsl();
402
        $twoWhiteBarRight = $imagickTwo->getImagePixelColor(30, 4)->getHsl();
403
404
        $twoImageLeft = $imagickTwo->getImagePixelColor(10, 4)->getHsl();
405
        $twoImageRight = $imagickTwo->getImagePixelColor(29, 4)->getHsl();
406
        $twoImageTop = $imagickTwo->getImagePixelColor(19, 0)->getHsl();
407
        $twoImageBottom = $imagickTwo->getImagePixelColor(19, 9)->getHsl();
408
409
        $this->assertGreaterThan(0.9, $twoWhiteBarLeft['luminosity']);
410
        $this->assertGreaterThan(0.9, $twoWhiteBarRight['luminosity']);
411
412
        $this->assertLessThan(0.1, $twoImageLeft['luminosity']);
413
        $this->assertLessThan(0.1, $twoImageRight['luminosity']);
414
        $this->assertLessThan(0.1, $twoImageTop['luminosity']);
415
        $this->assertLessThan(0.1, $twoImageBottom['luminosity']);
416
    }
417
418
    /**
419
     * @test
420
     * @covers ::resizeMulti
421
     */
422
    public function resizeMultiPerformance()
423
    {
424
        $source = new \Imagick('pattern:gray0');
425
        $source->scaleImage(2000, 500);
426
427
        $count = 10;
428
429
        $beforeSingle = microtime(true);
430
        for ($i = 0; $i < $count; ++$i) {
431
            Image::resize($source, 1100, 400);
432
            Image::resize($source, 100, 400);
433
            Image::resize($source, 10, 40);
434
        }
435
436
        $singleTime = microtime(true) - $beforeSingle;
437
438
        $beforeMulti = microtime(true);
439
        for ($i = 0; $i < $count; ++$i) {
440
            Image::resizeMulti(
441
                $source,
442
                [['width' => 1100, 'height' => 400], ['width' => 100, 'height' => 400], ['width' => 10, 'height' => 40]]
443
            );
444
        }
445
446
        $multiTime = microtime(true) - $beforeMulti;
447
448
        $this->assertLessThan($singleTime, $multiTime * 0.75);
449
    }
450
451
    /**
452
     * @test
453
     * @covers ::resizeMulti
454
     * @expectedException \InvalidArgumentException
455
     * @expectedExceptionMessage a width in a $boxSizes value was not an int
456
     */
457
    public function resizeMultiNonIntWidth()
458
    {
459
        Image::resizeMulti(new \Imagick(), [['width' => true, 'height' => 10]]);
460
    }
461
462
    /**
463
     * @test
464
     * @covers ::resizeMulti
465
     * @expectedException \InvalidArgumentException
466
     * @expectedExceptionMessage a height in a $boxSizes value was not an int
467
     */
468
    public function resizeMultiNonIntHeight()
469
    {
470
        Image::resizeMulti(new \Imagick(), [['width' => 10, 'height' => true]]);
471
    }
472
473
    /**
474
     * @test
475
     * @covers ::write
476
     */
477
    public function write()
478
    {
479
        $destPath = "{$this->_tempDir}/dest.jpeg";
480
481
        $source = new \Imagick("{$this->_sourceFilesDir}/exif.jpg");
482
        $source->setImageFormat('png');
483
484
        Image::write($source, $destPath, ['format' => 'jpeg', 'directoryMode' => 0775, 'fileMode' => 0776, 'stripHeaders' => true]);
485
486
        $destImage = new \Imagick($destPath);
487
488
        $this->assertSame(0, count($destImage->getImageProperties('exif:*')));
489
        $this->assertSame('JPEG', $destImage->getImageFormat());
490
491
        $directoryPermissions = substr(sprintf('%o', fileperms($this->_tempDir)), -4);
492
        $filePermissions = substr(sprintf('%o', fileperms($destPath)), -4);
493
494
        $this->assertSame('0775', $directoryPermissions);
495
        $this->assertSame('0776', $filePermissions);
496
    }
497
498
    /**
499
     * @test
500
     * @covers ::write
501
     * @expectedException \InvalidArgumentException
502
     * @expectedExceptionMessage $options["directoryMode"] was not an int
503
     */
504
    public function writeNonIntDirectoryMode()
505
    {
506
        Image::write(new \Imagick(), 'not under test', ['directoryMode' => 'not int']);
507
    }
508
509
    /**
510
     * @test
511
     * @covers ::write
512
     * @expectedException \InvalidArgumentException
513
     * @expectedExceptionMessage $options["fileMode"] was not an int
514
     */
515
    public function writeNonIntFileMode()
516
    {
517
        Image::write(new \Imagick(), 'not under test', ['fileMode' => 'not int']);
518
    }
519
520
    /**
521
     * @test
522
     * @covers ::write
523
     * @expectedException \InvalidArgumentException
524
     * @expectedExceptionMessage $options["format"] was not a string
525
     */
526
    public function writeNonStringFormat()
527
    {
528
        Image::write(new \Imagick(), 'not under test', ['format' => true]);
529
    }
530
531
    /**
532
     * @test
533
     * @covers ::write
534
     * @expectedException \InvalidArgumentException
535
     * @expectedExceptionMessage $options["stripHeaders"] was not a bool
536
     */
537
    public function writeNonBoolStripHeaders()
538
    {
539
        Image::write(new \Imagick(), 'not under test', ['stripHeaders' => 'not bool']);
540
    }
541
542
    /**
543
     * Verify that stripHeaders strips exif headers.
544
     *
545
     * @test
546
     * @covers ::stripHeaders
547
     */
548
    public function stripHeaders()
549
    {
550
        $path = "{$this->_tempDir}/stripHeaders.jpg";
551
552
        mkdir($this->_tempDir);
553
        copy("{$this->_sourceFilesDir}/exif.jpg", $path);
554
555
        Image::stripHeaders($path);
556
557
        $imagick = new \Imagick($path);
558
        $this->assertSame(0, count($imagick->getImageProperties('exif:*')));
559
    }
560
561
    /**
562
     * Verify that stripHeaders fails with a missing image.
563
     *
564
     * @test
565
     * @covers ::stripHeaders
566
     * @expectedException \ImagickException
567
     */
568
    public function stripHeadersMissingImage()
569
    {
570
        Image::stripHeaders("{$this->_tempDir}/doesnotexist.jpg");
571
    }
572
}
573