Completed
Push — master ( fa2217...770c68 )
by Emmanuel
02:17
created

GlLazyLoadImg::getLossyGifDataURI()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 10
nc 1
nop 2
1
<?php
2
3
/**
4
 * Lazy loading images
5
 *
6
 * PHP version 5.4
7
 *
8
 * @category  GLICER
9
 * @package   Contact
10
 * @author    Emmanuel ROECKER <[email protected]>
11
 * @author    Rym BOUCHAGOUR <[email protected]>
12
 * @copyright 2012-2013 GLICER
13
 * @license   Proprietary property of GLICER
14
 * @link      http://www.glicer.com
15
 *
16
 * Created : 8/26/16
17
 * File : GlLazyLoadImg.php
18
 *
19
 */
20
21
namespace GlLazyLoadImg;
22
23
use GlHtml\GlHtml;
24
25
class GlLazyLoadImg
26
{
27
    const BLANK = 0;
28
    const LOSSY = 1;
29
30
    /**
31
     * @var string rootpath
32
     */
33
    private $rootpath;
34
35
    /**
36
     * @var int
37
     */
38
    private $type;
39
40
41
    /**
42
     * @var string
43
     */
44
    private $moveToAttribute;
45
46
    /**
47
     * @var array
48
     */
49
    private $excludeAttributesList;
50
51
    /**
52
     * constructor - set root directory to relative url
53
     *
54
     * @param string $rootpath
55
     * @param int    $type
56
     * @param string $moveToAttribute
57
     * @param array  $excludeAttributesList
58
     */
59
    public function __construct(
60
        $rootpath,
61
        $type = self::BLANK,
62
        $moveToAttribute = 'data-original',
63
        array $excludeAttributesList = []
64
    ) {
65
        $this->rootpath              = $rootpath;
66
        $this->type                  = $type;
67
        $this->moveToAttribute       = $moveToAttribute;
68
        $this->excludeAttributesList = $excludeAttributesList;
69
    }
70
71
    /**
72
     * create lossy gif image and encode to data uri format
73
     * minimal size is jpeg
74
     *
75
     * @param     $src          resource GD library
76
     * @param int $minwidth     min width in pixels (height autocalculte)
77
     *
78
     * @return string           data uri format
79
     */
80
    public function getLossyGifDataURI($src, $minwidth = 75)
81
    {
82
        $src = imagescale($src, $minwidth, -1, IMG_NEAREST_NEIGHBOUR);
83
84
        ob_start();
85
        imagegif($src);
86
        $data = ob_get_contents();
87
        ob_end_clean();
88
89
        imagedestroy($src);
90
91
        $base64 = base64_encode($data);
92
93
        $mime = 'image/gif';
94
95
        return ('data:' . $mime . ';base64,' . $base64);
96
    }
97
98
    /**
99
     * create blank image with same size in data uri format
100
     * minimal size is gif
101
     *
102
     * @param int $red   red component background color (default 255)
103
     * @param int $green green component background color (default 255)
104
     * @param int $blue  blue component background color (default 255)
105
     *
106
     * @return string            data uri format
107
     */
108
    public function get1x1GifDataURI($red = 255, $green = 255, $blue = 255)
109
    {
110
        $img   = imagecreatetruecolor(1, 1);
111
        $bgcol = imagecolorallocate($img, $red, $green, $blue);
112
        imageFill($img, 0, 0, $bgcol);
113
114
        ob_start();
115
        imagegif($img);
116
        $data = ob_get_contents();
117
        ob_end_clean();
118
119
        $base64 = base64_encode($data);
120
121
        imagedestroy($img);
122
123
        $mime = 'image/gif';
124
125
        return ('data:' . $mime . ';base64,' . $base64);
126
    }
127
128
129
    /**
130
     * find type of image and open it
131
     *
132
     * @param string $file
133
     *
134
     * @return bool|resource
135
     */
136
    private function openImage($file)
137
    {
138
        if (!file_exists($file)) {
139
            return false;
140
        }
141
142
        $size = getimagesize($file);
143
        switch ($size["mime"]) {
144
            case "image/jpeg":
145
                $im = imagecreatefromjpeg($file);
146
                break;
147
            case "image/gif":
148
                $im = imagecreatefromgif($file);
149
                break;
150
            case "image/png":
151
                $im = imagecreatefrompng($file);
152
                break;
153
            default:
154
                $im = false;
155
                break;
156
        }
157
158
        return $im;
159
    }
160
161
    /**
162
     * replace all src attributes from img tags with datauri and set another attribute with old src value
163
     * support jpeg, png or gif file format
164
     *
165
     * @param string $html
166
     *
167
     * @throws \Exception
168
     * @return string
169
     */
170
    public function autoDataURI($html)
171
    {
172
        $html = new GlHtml($html);
173
        $imgs = $html->get('img');
174
        foreach ($imgs as $img) {
175
            $src          = $img->getAttribute('src');
176
            $pathimagesrc = $this->rootpath . '/' . $src;
177
178
            $imgbin = $this->openImage($pathimagesrc);
179
            if ($imgbin) {
180
                switch ($this->type) {
181
                    case self::BLANK:
182
                        $datauri = $this->get1x1GifDataURI();
183
                        break;
184
                    case self::LOSSY:
185
                        $datauri = $this->getLossyGifDataURI($imgbin);
186
                        break;
187
                    default:
188
                        throw new \Exception("Type unknown (only self::BLANK=0 or self::LOSSY=1 accepted) : " . $this->type);
189
                }
190
191
                $width  = imagesx($imgbin);
192
                $height = imagesy($imgbin);
193
                $img->setAttributes(['width' => $width, 'height' => $height]);
194
195
                if (!$img->hasAttributes($this->excludeAttributesList)) {
196
                    $img->setAttributes([$this->moveToAttribute => $src, 'src' => $datauri]);
197
                }
198
                imagedestroy($imgbin);
199
            }
200
        }
201
202
        return $html->html();
203
    }
204
}
205