Passed
Push — feat/lqip ( b3bc07...82f790 )
by Arnaud
05:16 queued 01:11
created

Image::isAnimatedGif()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 9
rs 10
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\Exception\RuntimeException;
17
use Intervention\Image\ImageManagerStatic as ImageManager;
18
19
class Image
20
{
21
    /**
22
     * Build the `srcset` attribute for responsive images.
23
     * e.g.: srcset="/img-480.jpg 480w, /img-800.jpg 800w".
24
     *
25
     * @throws RuntimeException
26
     */
27
    public static function buildSrcset(Asset $asset, array $widths): string
28
    {
29
        if ($asset['type'] !== 'image') {
30
            throw new RuntimeException(\sprintf('can\'t build "srcset" of "%s": it\'s not an image file.', $asset['path']));
31
        }
32
33
        $srcset = '';
34
        $widthMax = 0;
35
        foreach ($widths as $width) {
36
            if ($asset['width'] < $width) {
37
                break;
38
            }
39
            $img = $asset->resize($width);
40
            $srcset .= \sprintf('%s %sw, ', (string) $img, $width);
41
            $widthMax = $width;
42
        }
43
        rtrim($srcset, ', ');
44
        // add reference image
45
        if (!empty($srcset) && ($asset['width'] != $widthMax)) {
46
            $srcset .= \sprintf('%s %sw', (string) $asset, $asset['width']);
47
        }
48
49
        return $srcset;
50
    }
51
52
    /**
53
     * Checks if an asset is an animated gif.
54
     */
55
    public static function isAnimatedGif(Asset $asset): bool
56
    {
57
        // an animated gif contains multiple "frames", with each frame having a header made up of:
58
        // * a static 4-byte sequence (\x00\x21\xF9\x04)
59
        // * 4 variable bytes
60
        // * a static 2-byte sequence (\x00\x2C)
61
        $count = preg_match_all('#\x00\x21\xF9\x04.{4}\x00[\x2C\x21]#s', (string) $asset['content_source']);
62
63
        return $count > 1;
64
    }
65
66
    /**
67
     * Returns the dominant hex color of an image asset.
68
     *
69
     * @throws RuntimeException
70
     */
71
    public static function getDominantColor(Asset $asset): string
72
    {
73
        if ($asset['type'] !== 'image') {
74
            throw new RuntimeException(\sprintf('can\'t get dominant color of "%s": it\'s not an image file.', $asset['path']));
75
        }
76
77
        $assetColor = clone $asset;
78
        $assetColor = $assetColor->resize(100);
79
        $image = ImageManager::make($assetColor['content']);
80
        $color = $image->limitColors(1)->pickColor(0, 0, 'hex');
81
        $image->destroy();
82
83
        return $color;
84
    }
85
86
    /**
87
     * Returns a Low Quality Image Placeholder (LQIP) as data URL.
88
     *
89
     * @throws RuntimeException
90
     */
91
    public static function getLqip(Asset $asset): string
92
    {
93
        if ($asset['type'] !== 'image') {
94
            throw new RuntimeException(\sprintf('can\'t create LQIP of "%s": it\'s not an image file.', $asset['path']));
95
        }
96
97
        $assetLqip = clone $asset;
98
        $assetLqip = $assetLqip->resize(100);
99
        return (string) ImageManager::make($assetLqip['content'])->blur(50)->interlace()->encode('data-url');
100
    }
101
102
    /**
103
     * Returns the value of "sizes" corresponding to the configured class.
104
     */
105
    public static function getSizes(string $class, array $config): string
106
    {
107
        $classArray = explode(' ', $class);
108
        foreach ($classArray as $class) {
109
            if (array_key_exists($class, $config)) {
110
                $result = $config[$class] . ', ';
111
            }
112
        }
113
        if (!empty($result)) {
114
            return trim($result, ', ');
115
        }
116
117
        return $config['default'];
118
    }
119
}
120