1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace TraderInteractive\Util; |
4
|
|
|
|
5
|
|
|
use PHPUnit\Framework\Constraint\GreaterThan; |
6
|
|
|
use PHPUnit\Framework\TestCase; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* @coversDefaultClass \TraderInteractive\Util\Image |
10
|
|
|
* @covers ::<private> |
11
|
|
|
*/ |
12
|
|
|
final class ImageTest extends TestCase |
13
|
|
|
{ |
14
|
|
|
private $sourceFilesDir; |
15
|
|
|
private $tempDir; |
16
|
|
|
|
17
|
|
|
public function setUp() |
18
|
|
|
{ |
19
|
|
|
$this->sourceFilesDir = __DIR__ . '/_files'; |
20
|
|
|
$this->tempDir = sys_get_temp_dir() . '/imageUtilTest'; |
21
|
|
|
if (is_dir($this->tempDir)) { |
22
|
|
|
foreach (glob("{$this->tempDir}/*") as $file) { |
23
|
|
|
unlink($file); |
24
|
|
|
} |
25
|
|
|
|
26
|
|
|
rmdir($this->tempDir); |
27
|
|
|
} |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Downsize ratio 2.0 to 0.25 |
32
|
|
|
* |
33
|
|
|
* @test |
34
|
|
|
* @covers ::resize |
35
|
|
|
*/ |
36
|
|
|
public function resizeDownsizeToMoreVerticalAspect() |
37
|
|
|
{ |
38
|
|
|
$source = new \Imagick('pattern:gray0'); |
39
|
|
|
$source->scaleImage(100, 50); |
40
|
|
|
|
41
|
|
|
$imagick = Image::resize($source, 10, 40, ['color' => 'white', 'maxWidth' => 10000, 'maxHeight' => 10000]); |
42
|
|
|
|
43
|
|
|
//making sure source didnt resize |
44
|
|
|
$this->assertSame(100, $source->getImageWidth()); |
45
|
|
|
$this->assertSame(50, $source->getImageHeight()); |
46
|
|
|
|
47
|
|
|
$this->assertSame(10, $imagick->getImageWidth()); |
48
|
|
|
$this->assertSame(40, $imagick->getImageHeight()); |
49
|
|
|
|
50
|
|
|
$whiteBarTop = $imagick->getImagePixelColor(4, 16)->getHsl(); |
51
|
|
|
$whiteBarBottom = $imagick->getImagePixelColor(4, 22)->getHsl(); |
52
|
|
|
|
53
|
|
|
$imageLeft = $imagick->getImagePixelColor(0, 19)->getHsl(); |
54
|
|
|
$imageRight = $imagick->getImagePixelColor(9, 19)->getHsl(); |
55
|
|
|
$imageTop = $imagick->getImagePixelColor(4, 17)->getHsl(); |
56
|
|
|
$imageBottom = $imagick->getImagePixelColor(4, 21)->getHsl(); |
57
|
|
|
|
58
|
|
|
$this->assertGreaterThan(0.9, $whiteBarTop['luminosity']); |
59
|
|
|
$this->assertGreaterThan(0.9, $whiteBarBottom['luminosity']); |
60
|
|
|
|
61
|
|
|
$this->assertLessThan(0.1, $imageLeft['luminosity']); |
62
|
|
|
$this->assertLessThan(0.1, $imageRight['luminosity']); |
63
|
|
|
$this->assertLessThan(0.1, $imageTop['luminosity']); |
64
|
|
|
$this->assertLessThan(0.1, $imageBottom['luminosity']); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Downsize ratio 2.0 to 4.0 |
69
|
|
|
* |
70
|
|
|
* @test |
71
|
|
|
* @covers ::resize |
72
|
|
|
*/ |
73
|
|
View Code Duplication |
public function resizeDownsizeToMoreHorizontalAspect() |
|
|
|
|
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
|
|
|
*/ |
110
|
|
View Code Duplication |
public function resizeUpsizeToMoreHorizontalAspectWithoutGrow() |
|
|
|
|
111
|
|
|
{ |
112
|
|
|
$source = new \Imagick('pattern:gray0'); |
113
|
|
|
$source->scaleImage(100, 50); |
114
|
|
|
|
115
|
|
|
$imagick = Image::resize($source, 400, 100); |
116
|
|
|
|
117
|
|
|
//making sure source didnt resize |
118
|
|
|
$this->assertSame(100, $source->getImageWidth()); |
119
|
|
|
$this->assertSame(50, $source->getImageHeight()); |
120
|
|
|
|
121
|
|
|
$this->assertSame(400, $imagick->getImageWidth()); |
122
|
|
|
$this->assertSame(100, $imagick->getImageHeight()); |
123
|
|
|
|
124
|
|
|
$whiteBarLeft = $imagick->getImagePixelColor(99, 49)->getHsl(); |
125
|
|
|
$whiteBarRight = $imagick->getImagePixelColor(300, 49)->getHsl(); |
126
|
|
|
|
127
|
|
|
$imageTop = $imagick->getImagePixelColor(200, 26)->getHsl(); |
128
|
|
|
$imageBottom = $imagick->getImagePixelColor(200, 74)->getHsl(); |
129
|
|
|
$imageLeft = $imagick->getImagePixelColor(151, 50)->getHsl(); |
130
|
|
|
$imageRight = $imagick->getImagePixelColor(249, 50)->getHsl(); |
131
|
|
|
|
132
|
|
|
$this->assertGreaterThan(0.9, $whiteBarLeft['luminosity']); |
133
|
|
|
$this->assertGreaterThan(0.9, $whiteBarRight['luminosity']); |
134
|
|
|
|
135
|
|
|
$this->assertLessThan(0.1, $imageLeft['luminosity']); |
136
|
|
|
$this->assertLessThan(0.1, $imageRight['luminosity']); |
137
|
|
|
$this->assertLessThan(0.1, $imageTop['luminosity']); |
138
|
|
|
$this->assertLessThan(0.1, $imageBottom['luminosity']); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Upsize ratio 2.0 to 4.0 |
143
|
|
|
* |
144
|
|
|
* @test |
145
|
|
|
* @covers ::resize |
146
|
|
|
*/ |
147
|
|
View Code Duplication |
public function resizeUpsizeToMoreHorizontalAspectWithGrow() |
|
|
|
|
148
|
|
|
{ |
149
|
|
|
$source = new \Imagick('pattern:gray0'); |
150
|
|
|
$source->scaleImage(100, 50); |
151
|
|
|
|
152
|
|
|
$imagick = Image::resize($source, 400, 100, ['upsize' => true]); |
153
|
|
|
|
154
|
|
|
//making sure source didnt resize |
155
|
|
|
$this->assertSame(100, $source->getImageWidth()); |
156
|
|
|
$this->assertSame(50, $source->getImageHeight()); |
157
|
|
|
|
158
|
|
|
$this->assertSame(400, $imagick->getImageWidth()); |
159
|
|
|
$this->assertSame(100, $imagick->getImageHeight()); |
160
|
|
|
|
161
|
|
|
$whiteBarLeft = $imagick->getImagePixelColor(99, 49)->getHsl(); |
162
|
|
|
$whiteBarRight = $imagick->getImagePixelColor(300, 49)->getHsl(); |
163
|
|
|
|
164
|
|
|
$imageTop = $imagick->getImagePixelColor(249, 0)->getHsl(); |
165
|
|
|
$imageBottom = $imagick->getImagePixelColor(249, 99)->getHsl(); |
166
|
|
|
$imageLeft = $imagick->getImagePixelColor(100, 49)->getHsl(); |
167
|
|
|
$imageRight = $imagick->getImagePixelColor(299, 49)->getHsl(); |
168
|
|
|
|
169
|
|
|
$this->assertGreaterThan(0.9, $whiteBarLeft['luminosity']); |
170
|
|
|
$this->assertGreaterThan(0.9, $whiteBarRight['luminosity']); |
171
|
|
|
|
172
|
|
|
$this->assertLessThan(0.1, $imageLeft['luminosity']); |
173
|
|
|
$this->assertLessThan(0.1, $imageRight['luminosity']); |
174
|
|
|
$this->assertLessThan(0.1, $imageTop['luminosity']); |
175
|
|
|
$this->assertLessThan(0.1, $imageBottom['luminosity']); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* Upsize ratio 2.0 to 4.0 |
180
|
|
|
* |
181
|
|
|
* @test |
182
|
|
|
* @covers ::resize |
183
|
|
|
*/ |
184
|
|
View Code Duplication |
public function resizeUpsizeToMoreVerticalAspect() |
|
|
|
|
185
|
|
|
{ |
186
|
|
|
$source = new \Imagick('pattern:gray0'); |
187
|
|
|
$source->scaleImage(100, 50); |
188
|
|
|
|
189
|
|
|
$imagick = Image::resize($source, 200, 400); |
190
|
|
|
|
191
|
|
|
//making sure source didnt resize |
192
|
|
|
$this->assertSame(100, $source->getImageWidth()); |
193
|
|
|
$this->assertSame(50, $source->getImageHeight()); |
194
|
|
|
|
195
|
|
|
$this->assertSame(200, $imagick->getImageWidth()); |
196
|
|
|
$this->assertSame(400, $imagick->getImageHeight()); |
197
|
|
|
|
198
|
|
|
$whiteBarLeft = $imagick->getImagePixelColor(49, 200)->getHsl(); |
199
|
|
|
$whiteBarRight = $imagick->getImagePixelColor(151, 200)->getHsl(); |
200
|
|
|
|
201
|
|
|
$imageTop = $imagick->getImagePixelColor(100, 176)->getHsl(); |
202
|
|
|
$imageBottom = $imagick->getImagePixelColor(100, 224)->getHsl(); |
203
|
|
|
$imageLeft = $imagick->getImagePixelColor(51, 200)->getHsl(); |
204
|
|
|
$imageRight = $imagick->getImagePixelColor(149, 200)->getHsl(); |
205
|
|
|
|
206
|
|
|
$this->assertGreaterThan(0.9, $whiteBarLeft['luminosity']); |
207
|
|
|
$this->assertGreaterThan(0.9, $whiteBarRight['luminosity']); |
208
|
|
|
|
209
|
|
|
$this->assertLessThan(0.1, $imageLeft['luminosity']); |
210
|
|
|
$this->assertLessThan(0.1, $imageRight['luminosity']); |
211
|
|
|
$this->assertLessThan(0.1, $imageTop['luminosity']); |
212
|
|
|
$this->assertLessThan(0.1, $imageBottom['luminosity']); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* @test |
217
|
|
|
* @covers ::resize |
218
|
|
|
*/ |
219
|
|
|
public function resizeWithUpsizeAndBestFit() |
220
|
|
|
{ |
221
|
|
|
$source = new \Imagick('pattern:gray0'); |
222
|
|
|
$source->scaleImage(85, 45); |
223
|
|
|
$notBestFit = Image::resize($source, 300, 300, ['upsize' => true, 'bestfit' => false]); |
224
|
|
|
$this->assertSame('srgb(0,0,0)', $notBestFit->getImagePixelColor(299, 100)->getColorAsString()); |
225
|
|
|
$bestFit = Image::resize($source, 300, 300, ['upsize' => true, 'bestfit' => true]); |
226
|
|
|
$this->assertSame('srgb(255,255,255)', $bestFit->getImagePixelColor(299, 100)->getColorAsString()); |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* @test |
231
|
|
|
* @covers ::resize |
232
|
|
|
*/ |
233
|
|
View Code Duplication |
public function resizeWithColorOfBlur() |
|
|
|
|
234
|
|
|
{ |
235
|
|
|
$source = $this->getTestImage('portrait.jpg'); |
236
|
|
|
$actual = Image::resize($source, 1024, 768, ['upsize' => true, 'bestfit' => false, 'color' => 'blur']); |
237
|
|
|
$expected = $this->getTestImage('blur.jpg'); |
238
|
|
|
$this->assertSameImage($expected, $actual); |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* @test |
243
|
|
|
* @covers ::resize |
244
|
|
|
*/ |
245
|
|
View Code Duplication |
public function resizeWithBlurBackground() |
|
|
|
|
246
|
|
|
{ |
247
|
|
|
$source = $this->getTestImage('portrait.jpg'); |
248
|
|
|
$actual = Image::resize($source, 1024, 768, ['upsize' => true, 'bestfit' => false, 'blurBackground' => true]); |
249
|
|
|
$expected = $this->getTestImage('blur.jpg'); |
250
|
|
|
$this->assertSameImage($expected, $actual); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
/** |
254
|
|
|
* @test |
255
|
|
|
* @covers ::resize |
256
|
|
|
*/ |
257
|
|
View Code Duplication |
public function resizeWithBurredBackgroundWithCustomBlurValue() |
|
|
|
|
258
|
|
|
{ |
259
|
|
|
$source = $this->getTestImage('portrait.jpg'); |
260
|
|
|
$options = ['upsize' => true, 'bestfit' => false, 'blurBackground' => true, 'blurValue' => 30.0]; |
261
|
|
|
$actual = Image::resize($source, 1024, 768, $options); |
262
|
|
|
$expected = $this->getTestImage('blur-30.jpg'); |
263
|
|
|
$this->assertSameImage($expected, $actual); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* @test |
268
|
|
|
* @covers ::resize |
269
|
|
|
* @covers ::resizeMulti |
270
|
|
|
* @expectedException \InvalidArgumentException |
271
|
|
|
* @expectedExceptionMessage a $boxSizes width was not between 0 and $options["maxWidth"] |
272
|
|
|
*/ |
273
|
|
|
public function resizeZeroBoxWidth() |
274
|
|
|
{ |
275
|
|
|
Image::resize(new \Imagick(), 0, 10); |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* @test |
280
|
|
|
* @covers ::resize |
281
|
|
|
* @covers ::resizeMulti |
282
|
|
|
* @expectedException \InvalidArgumentException |
283
|
|
|
* @expectedExceptionMessage a $boxSizes width was not between 0 and $options["maxWidth"] |
284
|
|
|
*/ |
285
|
|
|
public function resizeLargeBoxWidth() |
286
|
|
|
{ |
287
|
|
|
Image::resize(new \Imagick(), 10001, 10, ['maxWidth' => 10000]); |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
/** |
291
|
|
|
* @test |
292
|
|
|
* @covers ::resize |
293
|
|
|
* @covers ::resizeMulti |
294
|
|
|
* @expectedException \InvalidArgumentException |
295
|
|
|
* @expectedExceptionMessage a $boxSizes height was not between 0 and $options["maxHeight"] |
296
|
|
|
*/ |
297
|
|
|
public function resizeZeroBoxHeight() |
298
|
|
|
{ |
299
|
|
|
Image::resize(new \Imagick(), 10, 0); |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
/** |
303
|
|
|
* @test |
304
|
|
|
* @covers ::resize |
305
|
|
|
* @covers ::resizeMulti |
306
|
|
|
* @expectedException \InvalidArgumentException |
307
|
|
|
* @expectedExceptionMessage a $boxSizes height was not between 0 and $options["maxHeight"] |
308
|
|
|
*/ |
309
|
|
|
public function resizeLargeBoxHeight() |
310
|
|
|
{ |
311
|
|
|
Image::resize(new \Imagick(), 10, 10001, ['maxHeight' => 10000]); |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
/** |
315
|
|
|
* @test |
316
|
|
|
* @covers ::resize |
317
|
|
|
* @covers ::resizeMulti |
318
|
|
|
* @expectedException \InvalidArgumentException |
319
|
|
|
* @expectedExceptionMessage $options["color"] was not a string |
320
|
|
|
*/ |
321
|
|
|
public function resizeNonStringColor() |
322
|
|
|
{ |
323
|
|
|
Image::resize(new \Imagick(), 10, 10, ['color' => 0]); |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* @test |
328
|
|
|
* @covers ::resize |
329
|
|
|
* @covers ::resizeMulti |
330
|
|
|
* @expectedException \InvalidArgumentException |
331
|
|
|
* @expectedExceptionMessage $options["maxWidth"] was not an int |
332
|
|
|
*/ |
333
|
|
|
public function resizeonIntMaxWidth() |
334
|
|
|
{ |
335
|
|
|
Image::resize(new \Imagick(), 10, 10, ['maxWidth' => 'not int']); |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* @test |
340
|
|
|
* @covers ::resize |
341
|
|
|
* @covers ::resizeMulti |
342
|
|
|
* @expectedException \InvalidArgumentException |
343
|
|
|
* @expectedExceptionMessage $options["maxHeight"] was not an int |
344
|
|
|
*/ |
345
|
|
|
public function resizeNonIntMaxHeight() |
346
|
|
|
{ |
347
|
|
|
Image::resize(new \Imagick(), 10, 10, ['maxHeight' => 'not int']); |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* @test |
352
|
|
|
* @covers ::resize |
353
|
|
|
* @covers ::resizeMulti |
354
|
|
|
* @expectedException \InvalidArgumentException |
355
|
|
|
* @expectedExceptionMessage $options["upsize"] was not a bool |
356
|
|
|
*/ |
357
|
|
|
public function resizeNonBoolUpsize() |
358
|
|
|
{ |
359
|
|
|
Image::resize(new \Imagick(), 10, 10, ['upsize' => 'not bool']); |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
/** |
363
|
|
|
* @test |
364
|
|
|
* @covers ::resize |
365
|
|
|
* @covers ::resizeMulti |
366
|
|
|
* @expectedException \InvalidArgumentException |
367
|
|
|
* @expectedExceptionMessage $options["bestfit"] was not a bool |
368
|
|
|
*/ |
369
|
|
|
public function resizeNonBoolBestFit() |
370
|
|
|
{ |
371
|
|
|
Image::resize(new \Imagick(), 10, 10, ['bestfit' => 'not bool']); |
372
|
|
|
} |
373
|
|
|
|
374
|
|
|
/** |
375
|
|
|
* Verify images are rotated according to EXIF header |
376
|
|
|
* @test |
377
|
|
|
* @covers ::resize |
378
|
|
|
*/ |
379
|
|
|
public function resizeOrientation() |
380
|
|
|
{ |
381
|
|
|
$files = [ |
382
|
|
|
"{$this->sourceFilesDir}/bottom-right.jpg", |
383
|
|
|
"{$this->sourceFilesDir}/left-bottom.jpg", |
384
|
|
|
"{$this->sourceFilesDir}/right-top.jpg", |
385
|
|
|
"{$this->sourceFilesDir}/top-left.jpg", |
386
|
|
|
]; |
387
|
|
|
|
388
|
|
|
$imageResults = []; |
389
|
|
|
|
390
|
|
|
foreach ($files as $file) { |
391
|
|
|
$source = new \Imagick($file); |
392
|
|
|
$imageWidth = $source->getimagewidth(); |
393
|
|
|
$imageHeight = $source->getimageheight(); |
394
|
|
|
$imageResults[] = Image::resize($source, $imageWidth, $imageHeight, []); |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
$this->assertSame( |
398
|
|
|
['r' => 254, 'g' => 0, 'b' => 0, 'a' => 1], |
399
|
|
|
$imageResults[0]->getImagePixelColor(0, 0)->getColor() |
400
|
|
|
); |
401
|
|
|
$this->assertSame( |
402
|
|
|
['r' => 0, 'g' => 0, 'b' => 0, 'a' => 1], |
403
|
|
|
$imageResults[1]->getImagePixelColor(0, 0)->getColor() |
404
|
|
|
); |
405
|
|
|
$this->assertSame( |
406
|
|
|
['r' => 0, 'g' => 255, 'b' => 1, 'a' => 1], |
407
|
|
|
$imageResults[2]->getImagePixelColor(0, 0)->getColor() |
408
|
|
|
); |
409
|
|
|
$this->assertSame( |
410
|
|
|
['r' => 0, 'g' => 0, 'b' => 254, 'a' => 1], |
411
|
|
|
$imageResults[3]->getImagePixelColor(0, 0)->getColor() |
412
|
|
|
); |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
/** |
416
|
|
|
* Downsize ratio 2.0 to 0.25 and 2.0 to 4.0 |
417
|
|
|
* |
418
|
|
|
* @test |
419
|
|
|
* @covers ::resizeMulti |
420
|
|
|
*/ |
421
|
|
|
public function resizeMultiDownsizeToMoreVerticalAndMoreHorizontalAspect() |
422
|
|
|
{ |
423
|
|
|
$source = new \Imagick('pattern:gray0'); |
424
|
|
|
$source->scaleImage(100, 50); |
425
|
|
|
|
426
|
|
|
$results = Image::resizeMulti($source, [['width' => 10, 'height' => 40], ['width' => 40, 'height' => 10]]); |
427
|
|
|
$imagickOne = $results[0]; |
428
|
|
|
$imagickTwo = $results[1]; |
429
|
|
|
|
430
|
|
|
//making sure source didnt resize |
431
|
|
|
$this->assertSame(100, $source->getImageWidth()); |
432
|
|
|
$this->assertSame(50, $source->getImageHeight()); |
433
|
|
|
|
434
|
|
|
//check $imagick1 |
435
|
|
|
|
436
|
|
|
$this->assertSame(10, $imagickOne->getImageWidth()); |
437
|
|
|
$this->assertSame(40, $imagickOne->getImageHeight()); |
438
|
|
|
|
439
|
|
|
$oneWhiteBarTop = $imagickOne->getImagePixelColor(4, 16)->getHsl(); |
440
|
|
|
$oneWhiteBarBottom = $imagickOne->getImagePixelColor(4, 22)->getHsl(); |
441
|
|
|
|
442
|
|
|
$oneImageLeft = $imagickOne->getImagePixelColor(0, 19)->getHsl(); |
443
|
|
|
$oneImageRight = $imagickOne->getImagePixelColor(9, 19)->getHsl(); |
444
|
|
|
$oneImageTop = $imagickOne->getImagePixelColor(4, 17)->getHsl(); |
445
|
|
|
$oneImageBottom = $imagickOne->getImagePixelColor(4, 21)->getHsl(); |
446
|
|
|
|
447
|
|
|
$this->assertGreaterThan(0.9, $oneWhiteBarTop['luminosity']); |
448
|
|
|
$this->assertGreaterThan(0.9, $oneWhiteBarBottom['luminosity']); |
449
|
|
|
|
450
|
|
|
$this->assertLessThan(0.1, $oneImageLeft['luminosity']); |
451
|
|
|
$this->assertLessThan(0.1, $oneImageRight['luminosity']); |
452
|
|
|
$this->assertLessThan(0.1, $oneImageTop['luminosity']); |
453
|
|
|
$this->assertLessThan(0.1, $oneImageBottom['luminosity']); |
454
|
|
|
|
455
|
|
|
//check $imagick2 |
456
|
|
|
|
457
|
|
|
$this->assertSame(40, $imagickTwo->getImageWidth()); |
458
|
|
|
$this->assertSame(10, $imagickTwo->getImageHeight()); |
459
|
|
|
|
460
|
|
|
$twoWhiteBarLeft = $imagickTwo->getImagePixelColor(9, 4)->getHsl(); |
461
|
|
|
$twoWhiteBarRight = $imagickTwo->getImagePixelColor(30, 4)->getHsl(); |
462
|
|
|
|
463
|
|
|
$twoImageLeft = $imagickTwo->getImagePixelColor(10, 4)->getHsl(); |
464
|
|
|
$twoImageRight = $imagickTwo->getImagePixelColor(29, 4)->getHsl(); |
465
|
|
|
$twoImageTop = $imagickTwo->getImagePixelColor(19, 0)->getHsl(); |
466
|
|
|
$twoImageBottom = $imagickTwo->getImagePixelColor(19, 9)->getHsl(); |
467
|
|
|
|
468
|
|
|
$this->assertGreaterThan(0.9, $twoWhiteBarLeft['luminosity']); |
469
|
|
|
$this->assertGreaterThan(0.9, $twoWhiteBarRight['luminosity']); |
470
|
|
|
|
471
|
|
|
$this->assertLessThan(0.1, $twoImageLeft['luminosity']); |
472
|
|
|
$this->assertLessThan(0.1, $twoImageRight['luminosity']); |
473
|
|
|
$this->assertLessThan(0.1, $twoImageTop['luminosity']); |
474
|
|
|
$this->assertLessThan(0.1, $twoImageBottom['luminosity']); |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
/** |
478
|
|
|
* @test |
479
|
|
|
* @covers ::resizeMulti |
480
|
|
|
*/ |
481
|
|
|
public function resizeMultiPerformance() |
482
|
|
|
{ |
483
|
|
|
$source = new \Imagick('pattern:gray0'); |
484
|
|
|
$source->scaleImage(2000, 500); |
485
|
|
|
|
486
|
|
|
$count = 10; |
487
|
|
|
|
488
|
|
|
$beforeSingle = microtime(true); |
489
|
|
|
for ($i = 0; $i < $count; ++$i) { |
490
|
|
|
Image::resizeMulti($source, [['width' => 1100, 'height' => 400]]); |
491
|
|
|
Image::resizeMulti($source, [['width' => 100, 'height' => 400]]); |
492
|
|
|
Image::resizeMulti($source, [['width' => 10, 'height' => 40]]); |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
$singleTime = microtime(true) - $beforeSingle; |
496
|
|
|
|
497
|
|
|
$beforeMulti = microtime(true); |
498
|
|
|
for ($i = 0; $i < $count; ++$i) { |
499
|
|
|
Image::resizeMulti( |
500
|
|
|
$source, |
501
|
|
|
[['width' => 1100, 'height' => 400], ['width' => 100, 'height' => 400], ['width' => 10, 'height' => 40]] |
502
|
|
|
); |
503
|
|
|
} |
504
|
|
|
|
505
|
|
|
$multiTime = microtime(true) - $beforeMulti; |
506
|
|
|
|
507
|
|
|
$this->assertLessThan($singleTime, $multiTime * 0.75); |
508
|
|
|
} |
509
|
|
|
|
510
|
|
|
/** |
511
|
|
|
* @test |
512
|
|
|
* @covers ::resizeMulti |
513
|
|
|
* @expectedException \InvalidArgumentException |
514
|
|
|
* @expectedExceptionMessage a width in a $boxSizes value was not an int |
515
|
|
|
*/ |
516
|
|
|
public function resizeMultiNonIntWidth() |
517
|
|
|
{ |
518
|
|
|
Image::resizeMulti(new \Imagick(), [['width' => true, 'height' => 10]]); |
519
|
|
|
} |
520
|
|
|
|
521
|
|
|
/** |
522
|
|
|
* @test |
523
|
|
|
* @covers ::resizeMulti |
524
|
|
|
* @expectedException \InvalidArgumentException |
525
|
|
|
* @expectedExceptionMessage a height in a $boxSizes value was not an int |
526
|
|
|
*/ |
527
|
|
|
public function resizeMultiNonIntHeight() |
528
|
|
|
{ |
529
|
|
|
Image::resizeMulti(new \Imagick(), [['width' => 10, 'height' => true]]); |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
/** |
533
|
|
|
* @test |
534
|
|
|
* @covers ::resize |
535
|
|
|
*/ |
536
|
|
View Code Duplication |
public function resizeTransparentImageWithTransparentBackground() |
|
|
|
|
537
|
|
|
{ |
538
|
|
|
$source = $this->getTestImage('transparent.png'); |
539
|
|
|
$actual = Image::resize($source, 128, 128, ['color' => 'transparent']); |
540
|
|
|
$expected = $this->getTestImage('transparent-resize.png'); |
541
|
|
|
$this->assertSameImage($expected, $actual); |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
/** |
545
|
|
|
* @test |
546
|
|
|
* @covers ::resize |
547
|
|
|
*/ |
548
|
|
View Code Duplication |
public function resizeTransparentImageWithColorBackground() |
|
|
|
|
549
|
|
|
{ |
550
|
|
|
$source = $this->getTestImage('transparent.png'); |
551
|
|
|
$actual = Image::resize($source, 128, 128, ['color' => 'green']); |
552
|
|
|
$expected = $this->getTestImage('transparent-resize-color.png'); |
553
|
|
|
$this->assertSameImage($expected, $actual); |
554
|
|
|
} |
555
|
|
|
|
556
|
|
|
/** |
557
|
|
|
* @test |
558
|
|
|
* @covers ::resize |
559
|
|
|
*/ |
560
|
|
View Code Duplication |
public function resizeTransparentImageWithUpsize() |
|
|
|
|
561
|
|
|
{ |
562
|
|
|
$source = $this->getTestImage('transparent.png'); |
563
|
|
|
$actual = Image::resize($source, 128, 128, ['upsize' => true]); |
564
|
|
|
$expected = $this->getTestImage('transparent-upsize.png'); |
565
|
|
|
$this->assertSameImage($expected, $actual); |
566
|
|
|
} |
567
|
|
|
|
568
|
|
|
/** |
569
|
|
|
* @test |
570
|
|
|
* @covers ::resize |
571
|
|
|
*/ |
572
|
|
View Code Duplication |
public function resizeTransparentImageWithColorOfBlur() |
|
|
|
|
573
|
|
|
{ |
574
|
|
|
$source = $this->getTestImage('transparent.png'); |
575
|
|
|
$actual = Image::resize($source, 128, 128, ['color' => 'blur']); |
576
|
|
|
$expected = $this->getTestImage('transparent-blur.png'); |
577
|
|
|
$this->assertSameImage($expected, $actual); |
578
|
|
|
} |
579
|
|
|
|
580
|
|
|
/** |
581
|
|
|
* @test |
582
|
|
|
* @covers ::resize |
583
|
|
|
*/ |
584
|
|
View Code Duplication |
public function resizeTransparentImageWithBlurBackground() |
|
|
|
|
585
|
|
|
{ |
586
|
|
|
$source = $this->getTestImage('transparent.png'); |
587
|
|
|
$actual = Image::resize($source, 128, 128, ['blurBackground' => true]); |
588
|
|
|
$expected = $this->getTestImage('transparent-blur.png'); |
589
|
|
|
$this->assertSameImage($expected, $actual); |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
/** |
593
|
|
|
* @test |
594
|
|
|
* @covers ::write |
595
|
|
|
*/ |
596
|
|
|
public function write() |
597
|
|
|
{ |
598
|
|
|
$destPath = "{$this->tempDir}/dest.jpeg"; |
599
|
|
|
|
600
|
|
|
$source = new \Imagick("{$this->sourceFilesDir}/exif.jpg"); |
601
|
|
|
$source->setImageFormat('png'); |
602
|
|
|
|
603
|
|
|
Image::write( |
604
|
|
|
$source, |
605
|
|
|
$destPath, |
606
|
|
|
['format' => 'jpeg', 'directoryMode' => 0775, 'fileMode' => 0776, 'stripHeaders' => true] |
607
|
|
|
); |
608
|
|
|
|
609
|
|
|
$destImage = new \Imagick($destPath); |
610
|
|
|
|
611
|
|
|
$this->assertSame(0, count($destImage->getImageProperties('exif:*'))); |
612
|
|
|
$this->assertSame('JPEG', $destImage->getImageFormat()); |
613
|
|
|
|
614
|
|
|
$directoryPermissions = substr(sprintf('%o', fileperms($this->tempDir)), -4); |
615
|
|
|
$filePermissions = substr(sprintf('%o', fileperms($destPath)), -4); |
616
|
|
|
|
617
|
|
|
$this->assertSame('0775', $directoryPermissions); |
618
|
|
|
$this->assertSame('0776', $filePermissions); |
619
|
|
|
} |
620
|
|
|
|
621
|
|
|
/** |
622
|
|
|
* @test |
623
|
|
|
* @covers ::write |
624
|
|
|
* @expectedException \InvalidArgumentException |
625
|
|
|
* @expectedExceptionMessage $options["directoryMode"] was not an int |
626
|
|
|
*/ |
627
|
|
|
public function writeNonIntDirectoryMode() |
628
|
|
|
{ |
629
|
|
|
Image::write(new \Imagick(), 'not under test', ['directoryMode' => 'not int']); |
630
|
|
|
} |
631
|
|
|
|
632
|
|
|
/** |
633
|
|
|
* @test |
634
|
|
|
* @covers ::write |
635
|
|
|
* @expectedException \InvalidArgumentException |
636
|
|
|
* @expectedExceptionMessage $options["fileMode"] was not an int |
637
|
|
|
*/ |
638
|
|
|
public function writeNonIntFileMode() |
639
|
|
|
{ |
640
|
|
|
Image::write(new \Imagick(), 'not under test', ['fileMode' => 'not int']); |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
/** |
644
|
|
|
* @test |
645
|
|
|
* @covers ::write |
646
|
|
|
* @expectedException \InvalidArgumentException |
647
|
|
|
* @expectedExceptionMessage $options["format"] was not a string |
648
|
|
|
*/ |
649
|
|
|
public function writeNonStringFormat() |
650
|
|
|
{ |
651
|
|
|
Image::write(new \Imagick(), 'not under test', ['format' => true]); |
652
|
|
|
} |
653
|
|
|
|
654
|
|
|
/** |
655
|
|
|
* @test |
656
|
|
|
* @covers ::write |
657
|
|
|
* @expectedException \InvalidArgumentException |
658
|
|
|
* @expectedExceptionMessage $options["stripHeaders"] was not a bool |
659
|
|
|
*/ |
660
|
|
|
public function writeNonBoolStripHeaders() |
661
|
|
|
{ |
662
|
|
|
Image::write(new \Imagick(), 'not under test', ['stripHeaders' => 'not bool']); |
663
|
|
|
} |
664
|
|
|
|
665
|
|
|
/** |
666
|
|
|
* Verify that stripHeaders strips exif headers. |
667
|
|
|
* |
668
|
|
|
* @test |
669
|
|
|
* @covers ::stripHeaders |
670
|
|
|
*/ |
671
|
|
|
public function stripHeaders() |
672
|
|
|
{ |
673
|
|
|
$path = "{$this->tempDir}/stripHeaders.jpg"; |
674
|
|
|
|
675
|
|
|
mkdir($this->tempDir); |
676
|
|
|
copy("{$this->sourceFilesDir}/exif.jpg", $path); |
677
|
|
|
|
678
|
|
|
Image::stripHeaders($path); |
679
|
|
|
|
680
|
|
|
$imagick = new \Imagick($path); |
681
|
|
|
$this->assertSame(0, count($imagick->getImageProperties('exif:*'))); |
682
|
|
|
} |
683
|
|
|
|
684
|
|
|
/** |
685
|
|
|
* Verify that stripHeaders fails with a missing image. |
686
|
|
|
* |
687
|
|
|
* @test |
688
|
|
|
* @covers ::stripHeaders |
689
|
|
|
* @expectedException \ImagickException |
690
|
|
|
*/ |
691
|
|
|
public function stripHeadersMissingImage() |
692
|
|
|
{ |
693
|
|
|
Image::stripHeaders("{$this->tempDir}/doesnotexist.jpg"); |
694
|
|
|
} |
695
|
|
|
|
696
|
|
|
private function assertSameImage(\Imagick $expected, \Imagick $actual) |
697
|
|
|
{ |
698
|
|
|
$comparison = $expected->compareImages($actual, \Imagick::METRIC_UNDEFINED); |
699
|
|
|
$this->assertThat($comparison[1], new GreaterThan(.99)); |
700
|
|
|
} |
701
|
|
|
|
702
|
|
|
private function getTestImage(string $filename) : \Imagick |
703
|
|
|
{ |
704
|
|
|
$image = new \Imagick(); |
705
|
|
|
$image->readImage("{$this->sourceFilesDir}/{$filename}"); |
706
|
|
|
return $image; |
707
|
|
|
} |
708
|
|
|
} |
709
|
|
|
|
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.