Passed
Push — fix/serve-timeout ( 697f77...233bc8 )
by Arnaud
04:27
created

Image   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 88
Duplicated Lines 0 %

Test Coverage

Coverage 73.17%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 43
dl 0
loc 88
ccs 30
cts 41
cp 0.7317
rs 10
c 2
b 1
f 0
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A isAnimatedGif() 0 9 1
A convertTopWebp() 0 10 1
A buildSrcset() 0 17 4
A optimizer() 0 30 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Cecil.
7
 *
8
 * Copyright (c) Arnaud Ligny <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Cecil\Assets;
15
16
use Cecil\Assets\Image\Optimizers\Cwebp;
17
use Intervention\Image\ImageManagerStatic as ImageManager;
18
use Spatie\ImageOptimizer\OptimizerChain;
19
use Spatie\ImageOptimizer\Optimizers\Gifsicle;
20
use Spatie\ImageOptimizer\Optimizers\Jpegoptim;
21
use Spatie\ImageOptimizer\Optimizers\Optipng;
22
use Spatie\ImageOptimizer\Optimizers\Pngquant;
23
use Spatie\ImageOptimizer\Optimizers\Svgo;
24
25
class Image
26 1
{
27
    /**
28 1
     * Image Optimizer Chain.
29 1
     */
30 1
    public static function optimizer(int $quality): OptimizerChain
31 1
    {
32 1
        return (new OptimizerChain())
33
            ->addOptimizer(new Jpegoptim([
34 1
                "--max=$quality",
35 1
                '--strip-all',
36 1
                '--all-progressive',
37 1
            ]))
38
            ->addOptimizer(new Pngquant([
39 1
                "--quality=$quality",
40 1
                '--force',
41
                '--skip-if-larger',
42
            ]))
43
            ->addOptimizer(new Optipng([
44 1
                '-i0',
45 1
                '-o2',
46
                '-quiet',
47 1
            ]))
48 1
            ->addOptimizer(new Svgo([
49
                '--disable={cleanupIDs,removeViewBox}',
50
            ]))
51
            ->addOptimizer(new Gifsicle([
52
                '-b',
53
                '-O3',
54
            ]))
55
            ->addOptimizer(new Cwebp([
56
                '-m 6',
57 1
                '-pass 10',
58
                '-mt',
59 1
                '-q $quality',
60 1
            ]));
61 1
    }
62 1
63 1
    /**
64
     * Build the `srcset` attribute for responsive images.
65 1
     * ie: srcset="/img-480.jpg 480w, /img-800.jpg 800w".
66 1
     */
67 1
    public static function buildSrcset(Asset $asset, array $widths): string
68 1
    {
69 1
        $srcset = '';
70
        foreach ($widths as $width) {
71
            if ($asset->getWidth() < $width) {
72
                break;
73 1
            }
74 1
            $img = $asset->resize($width);
75
            $srcset .= \sprintf('%s %sw, ', $img, $width);
76
        }
77 1
        rtrim($srcset, ', ');
78
        // add reference image
79
        if (!empty($srcset)) {
80
            $srcset .= \sprintf('%s %sw', (string) $asset, $asset->getWidth());
81
        }
82
83
        return $srcset;
84
    }
85
86
    /**
87
     * Converts an asset image to WebP.
88
     */
89
    public static function convertTopWebp(Asset $asset, int $quality): Asset
90
    {
91
        $assetWebp = clone $asset;
92
        $format = 'webp';
93
        $image = ImageManager::make($assetWebp['content']);
94
        $assetWebp['content'] = (string) $image->encode($format, $quality);
95
        $assetWebp['path'] = preg_replace('/\.'.$asset['ext'].'$/m', ".$format", $asset['path']);
96
        $assetWebp['ext'] = $format;
97
98
        return $assetWebp;
99
    }
100
101
    /**
102
     * Tests if an asset is an animated gif.
103
     */
104
    public static function isAnimatedGif(Asset $asset): bool
105
    {
106
        // an animated gif contains multiple "frames", with each frame having a header made up of:
107
        // * a static 4-byte sequence (\x00\x21\xF9\x04)
108
        // * 4 variable bytes
109
        // * a static 2-byte sequence (\x00\x2C)
110
        $count = preg_match_all('#\x00\x21\xF9\x04.{4}\x00[\x2C\x21]#s', (string) $asset['content_source']);
111
112
        return $count > 1;
113
    }
114
}
115