Completed
Push — master ( debe1f...8b07a4 )
by Emmanuel
03:07
created

GlLazyLoadImg::getBlankDataURI()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 18
nc 2
nop 5
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
    private function gcd($a,$b) {
73
         return ($a % $b) ? $this->gcd($b,$a % $b) : $b;
74
    }
75
    
76
    /**
77
     * create lossy image and encode to data uri format
78
     * minimal size is jpeg
79
     *
80
     * @param     $src          resource GD library
81
     * @param int $quality      jpeg quality from 0 (poor quality) to 100 (best quality) - default 0
82
     * @param bool $minsize     rescale to min size (default true)
83
     * @return string
84
     */
85
    public function getLossyDataURI($src, $quality = 0, $minsize = true)
86
    {
87
        if ($minsize) {
88
            $width  = imagesx($src);
89
            $height = imagesy($src);
90
91
            $gcd    = $this->gcd($width, $height);
92
            $width  = $width / $gcd;
93
            $height = $height / $gcd;
94
            
95
            $src = imagescale($src,$width,$height,IMG_NEAREST_NEIGHBOUR);
96
        }
97
        
98
        ob_start();
99
        imagejpeg($src, null, $quality);
100
        $data = ob_get_contents();
101
        ob_end_clean();
102
103
        if ($minsize) {
104
            imagedestroy($src);
105
        }
106
        
107
        $base64 = base64_encode($data);
108
109
        $mime = 'image/jpeg';
110
      
111
        return ('data:' . $mime . ';base64,' . $base64);
112
    }
113
114
    /**
115
     * create blank image with same size in data uri format
116
     * minimal size is gif
117
     *
118
     * @param      $src          resource GD library
119
     * @param int  $red          red component background color (default 255)
120
     * @param int  $green        green component background color (default 255)
121
     * @param int  $blue         blue component background color (default 255)
122
     * @param bool $minsize      rescale to min size (default true)
123
     *
124
     * @return string
125
     */
126
    public function getBlankDataURI($src, $red = 255, $green = 255, $blue = 255, $minsize = true)
127
    {
128
        $width  = imagesx($src);
129
        $height = imagesy($src);
130
131
        if ($minsize) {
132
            $gcd    = $this->gcd($width, $height);
133
            $width  = $width / $gcd;
134
            $height = $height / $gcd;
135
        }
136
        
137
        $img   = imagecreatetruecolor($width, $height);
138
        $bgcol = imagecolorallocate($img, $red, $green, $blue);
139
        imageFill($img, 0, 0, $bgcol);
140
141
        ob_start();
142
        imagegif($img);
143
        $data = ob_get_contents();
144
        ob_end_clean();
145
146
        $base64 = base64_encode($data);
147
148
        imagedestroy($img);
149
150
        $mime = 'image/gif';
151
152
        return ('data:' . $mime . ';base64,' . $base64);
153
    }
154
155
156
    /**
157
     * find type of image and open it
158
     *
159
     * @param string $file
160
     *
161
     * @return bool|resource
162
     */
163
    private function openImage($file)
164
    {
165
        if (!file_exists($file)) {
166
            return false;
167
        }
168
169
        $size = getimagesize($file);
170
        switch ($size["mime"]) {
171
            case "image/jpeg":
172
                $im = imagecreatefromjpeg($file);
173
                break;
174
            case "image/gif":
175
                $im = imagecreatefromgif($file);
176
                break;
177
            case "image/png":
178
                $im = imagecreatefrompng($file);
179
                break;
180
            default:
181
                $im = false;
182
                break;
183
        }
184
185
        return $im;
186
    }
187
188
    /**
189
     * replace all src attributes from img tags with datauri and set another attribute with old src value
190
     * support jpeg, png or gif file format
191
     *
192
     * @param string $html
193
     * @param bool   $minsize  rescale to minsize (default true)
194
     * 
195
     * @throws \Exception
196
     * @return string
197
     */
198
    public function autoDataURI($html, $minsize=true)
199
    {
200
        $html = new GlHtml($html);
201
        $imgs = $html->get('img');
202
        foreach ($imgs as $img) {
203
            $src          = $img->getAttribute('src');
204
            $pathimagesrc = $this->rootpath . '/' . $src;
205
206
            $imgbin = $this->openImage($pathimagesrc);
207
            if ($imgbin) {
208
                switch ($this->type) {
209
                    case self::BLANK:
210
                        $datauri = $this->getBlankDataURI($imgbin);
211
                        break;
212
                    case self::LOSSY:
213
                        $datauri = $this->getLossyDataURI($imgbin);
214
                        break;
215
                    default:
216
                        throw new \Exception("Type unknown (only self::BLANK=0 or self::LOSSY=1 accepted) : " . $this->type);
217
                }
218
219
                if ($minsize) {
220
                    // keep original size
221
                    $width  = imagesx($imgbin);
222
                    $height = imagesy($imgbin);
223
                    $img->setAttributes(['width' => $width, 'height' => $height]);
224
                }
225
226
                if (!$img->hasAttributes($this->excludeAttributesList)) {
227
                    $img->setAttributes([$this->moveToAttribute => $src, 'src' => $datauri]);
228
                }
229
                imagedestroy($imgbin);
230
            }
231
        }
232
233
        return $html->html();
234
    }
235
236
    /**
237
     * @param string $html
238
     *
239
     * @throws \Exception
240
     * @return string
241
     */
242
    public function autoWidthHeight($html)
243
    {
244
        $html = new GlHtml($html);
245
        $imgs = $html->get('img');
246
        foreach ($imgs as $img) {
247
            $src          = $img->getAttribute('src');
248
            $pathimagesrc = $this->rootpath . '/' . $src;
249
250
            $imgbin = $this->openImage($pathimagesrc);
251
            if ($imgbin) {
252
                $width  = imagesx($imgbin);
253
                $height = imagesy($imgbin);
254
                $img->setAttributes(['width' => $width, 'height' => $height]);
255
256
                if (!$img->hasAttributes($this->excludeAttributesList)) {
257
                    $img->setAttributes(['data-original' => $src, 'src' => '#']);
258
                }
259
                imagedestroy($imgbin);
260
            }
261
        }
262
263
        return $html->html();
264
    }
265
}
266