source: spip-zone/_plugins_/image_responsive/image_responsive_options.php @ 115278

Last change on this file since 115278 was 115278, checked in by arno@…, 6 weeks ago

Gros changement de qualité sur écrans Retina: on va directement chercher l’image deux fois plus grande mais avec le taux de compression JPG usuel. Possibilité de revenir à la version précédente (images Retina super-compressées) avec:
define("_IMAGE_RESPONSIVE_RETINA_HQ", false);

File size: 8.9 KB
Line 
1<?php
2
3if (!defined('_ECRIRE_INC_VERSION')) {
4        return;
5}
6
7
8if (!defined("_IMAGE_RESPONSIVE_CALCULER")) define("_IMAGE_RESPONSIVE_CALCULER", false);
9if (!defined("_SPIP_LIER_RESSOURCES")) define("_SPIP_LIER_RESSOURCES", false);
10if (!defined("_IMAGE_RESPONSIVE_RETINA_HQ")) define("_IMAGE_RESPONSIVE_RETINA_HQ", true);
11
12function _findSharp($intOrig, $intFinal) {
13  $intFinal = $intFinal * (750.0 / $intOrig);
14  $intA     = 52;
15  $intB     = -0.27810650887573124;
16  $intC     = .00047337278106508946;
17  $intRes   = $intA + $intB * $intFinal + $intC * $intFinal * $intFinal;
18  return max(round($intRes), 0);
19}
20
21
22function image_reduire_net($source, $taille = 0, $taille_y=0, $dpr=0) {
23        // ordre de preference des formats graphiques pour creer les vignettes
24        // le premier format disponible, selon la methode demandee, est utilise
25
26        // initialisations
27        $force = false;
28        $test_cache_only = false;
29
30        //$force = true;
31        include_spip('inc/filtres_images_lib_mini');
32       
33        if ($dpr > 1) {
34                $taille = $taille * $dpr;
35                $taille_y = $taille_y * $dpr;   
36        }
37
38        if ($taille == 0 AND $taille_y > 0)
39                $taille = 10000; # {0,300} -> c'est 300 qui compte
40        elseif ($taille > 0 AND $taille_y == 0)
41                $taille_y = 10000; # {300,0} -> c'est 300 qui compte
42        elseif ($taille == 0 AND $taille_y == 0)
43                return '';
44
45        $valeurs = _image_valeurs_trans($source, "reduire_net-{$taille}-{$taille_y}-{$dpr}", false);
46        $image = $valeurs['fichier'];
47        $format = $valeurs['format_source'];
48
49        $destdir = dirname($valeurs['fichier_dest']);
50        $destfile = basename($valeurs['fichier_dest'],".".$valeurs["format_dest"]);
51
52
53       
54        $format_sortie = $valeurs['format_dest'];
55       
56        // liste des formats qu'on sait lire
57        $img = isset($GLOBALS['meta']['formats_graphiques'])
58          ? (strpos($GLOBALS['meta']['formats_graphiques'], $format)!==false)
59          : false;
60
61        // si le doc n'est pas une image, refuser
62        if (!$force AND !$img) return;
63        $destination = "$destdir/$destfile";
64
65
66        // chercher un cache
67        $vignette = '';
68        if ($test_cache_only AND !$vignette) return;
69
70        // utiliser le cache ?
71        if (!$test_cache_only)
72        if ($force OR !$vignette OR (@filemtime($vignette) < @filemtime($image))) {
73
74                $creation = true;
75                // calculer la taille
76                if (($srcWidth=$valeurs['largeur']) && ($srcHeight=$valeurs['hauteur'])){
77                        if (!($destWidth=$valeurs['largeur_dest']) || !($destHeight=$valeurs['hauteur_dest'])) {
78                                list ($destWidth, $destHeight) = _image_ratio($valeurs['largeur'], $valeurs['hauteur'], $maxWidth, $maxHeight);
79                        }
80                }
81                else {
82                        $destWidth = $maxWidth;
83                        $destHeight = $maxHeight;
84                }
85
86                // Si l'image est de la taille demandee (ou plus petite), simplement
87                // la retourner
88                if ($srcWidth
89                AND $srcWidth <= $maxWidth AND $srcHeight <= $maxHeight) {
90                        $vignette = $destination.'.'.$format;
91                        @copy($image, $vignette);
92                }
93                else {
94                        if (_IMG_GD_MAX_PIXELS && $srcWidth*$srcHeight>_IMG_GD_MAX_PIXELS){
95                                spip_log("vignette gd1/gd2 impossible : ".$srcWidth*$srcHeight."pixels");
96                                return $image;
97                        }
98                        $destFormat = $format_sortie;
99                        if (!$destFormat) {
100                                spip_log("pas de format pour $image");
101                                return;
102                        }
103                       
104                        $fonction_imagecreatefrom = $valeurs['fonction_imagecreatefrom'];
105                        if (!function_exists($fonction_imagecreatefrom))
106                                return '';
107                        $srcImage = @$fonction_imagecreatefrom($image);
108                        if (!$srcImage) { 
109                                spip_log("echec gd1/gd2"); 
110                                return $image; 
111                        } 
112                       
113                        // Initialisation de l'image destination
114                        if ($destFormat != "gif") 
115                                $destImage = ImageCreateTrueColor($destWidth, $destHeight); 
116                        if (!$destImage) 
117                                $destImage = ImageCreate($destWidth, $destHeight); 
118
119                        // Recopie de l'image d'origine avec adaptation de la taille
120                        $ok = false; 
121                        if (function_exists('ImageCopyResampled')) { 
122                                if ($format == "gif") { 
123                                        // Si un GIF est transparent,
124                                        // fabriquer un PNG transparent 
125                                        $transp = imagecolortransparent($srcImage); 
126                                        if ($transp > 0) $destFormat = "png"; 
127                                }
128                                if ($destFormat == "png") { 
129                                        // Conserver la transparence
130                                        if (function_exists("imageAntiAlias")) imageAntiAlias($destImage,true); 
131                                        @imagealphablending($destImage, false); 
132                                        @imagesavealpha($destImage,true); 
133                                }
134                                $ok = @ImageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
135                        }
136                        if (!$ok)
137                                $ok = ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
138                       
139                        //die (phpversion());
140                       
141                        if($destFormat == "jpg" && function_exists('imageconvolution')) {
142                                $intSharpness = _findSharp($srcWidth, $destWidth);
143                                $arrMatrix = array(
144                                        array(-1, -2, -1),
145                                        array(-2, $intSharpness + 12, -2),
146                                        array(-1, -2, -1)
147                                );
148                               
149                                $div = array_sum(array_map('array_sum', $arrMatrix)); 
150                                //die ("div: ".$div);
151                               
152                                // On s'arrange maintenant pour que le divisor soit 1
153                                // parce qu'imageconvoluion en PHP 5.5.9 semble ne prendre en compte
154                                // que cette valeur
155                                $arrMatrix = array(
156                                        array(-1/$div, -2/$div, -1/$div),
157                                        array(-2/$div, ($intSharpness + 12)/$div, -2/$div),
158                                        array(-1/$div, -2/$div, -1/$div)
159                                );
160                                $divisor = array_sum(array_map('array_sum', $arrMatrix));           
161                                //die ("divisor: ".$divisor);
162                                                               
163
164                                imageconvolution($destImage, $arrMatrix, $divisor, 0);
165                        }
166                        // Sauvegarde de l'image destination
167                        $valeurs['fichier_dest'] = $vignette = "$destination.$destFormat";
168                        $valeurs['format_dest'] = $format = $destFormat;
169                       
170                        if ($dpr > 1.5) $qualite = 40;
171                        else $qualite=_IMG_GD_QUALITE;
172                        _image_gd_output($destImage,$valeurs, $qualite);
173
174                        if ($srcImage)
175                                ImageDestroy($srcImage);
176                        ImageDestroy($destImage);
177                }
178        }
179        $size = @getimagesize($vignette);
180        // Gaffe: en safe mode, pas d'acces a la vignette,
181        // donc risque de balancer "width='0'", ce qui masque l'image sous MSIE
182        if ($size[0] < 1) $size[0] = $destWidth;
183        if ($size[1] < 1) $size[1] = $destHeight;
184       
185        $largeur = $size[0];
186        $hauteur = $size[1];
187        $date = @filemtime($vignette);
188       
189
190        // dans l'espace prive mettre un timestamp sur l'adresse
191        // de l'image, de facon a tromper le cache du navigateur
192        // quand on fait supprimer/reuploader un logo
193        // (pas de filemtime si SAFE MODE)
194        $date = test_espace_prive() ? ('?'.$date) : '';
195
196        return _image_ecrire_tag(
197                $valeurs,
198                array('src'=>"$vignette",
199                'width'=>$largeur,
200                'height'=>$hauteur)
201        );
202
203}
204
205
206
207function retour_image_responsive($img, $taille, $dpr, $xsendfile, $retour="http"){
208        if (!preg_match(',\.(gif|jpe?g|png)$,i', $img)
209        OR !preg_match(',^\d+v?$,', $taille)
210        OR !preg_match(',^[\d\.]*$,', $dpr)
211        OR !file_exists($img)) {
212                if($retour == "http") {
213                        header('HTTP/1.1 500 Internal Server Error');
214                        die( "Erreur" );
215                } else {
216                        return find_in_path("rien.gif");
217                }
218        } else {
219
220                include_spip("inc/filtres");
221                if (preg_match("/([0-9]+)v$/", $taille, $regs)) {
222                        $taille = $regs[1];
223                        $v = true;
224                        // if ($taille == hauteur($img)) return timestamp($img);
225                        $taille = min($taille, hauteur($img));
226                } else {
227                        $v = false;
228                        // if ($taille == largeur($img)) return timestamp($img);
229                        $taille = min($taille, largeur($img));
230                }
231
232       
233                $terminaison = substr($img, strlen($img)-3, 3);
234                $base = sous_repertoire(_DIR_VAR, "cache-responsive");
235                $base = sous_repertoire($base, "cache-".$taille);
236                $dest = md5($img);
237                if ($dpr > 1) $dest .= "$dest-$dpr";
238                else $dpr = false;
239               
240                $dest = $base.$dest.".".$terminaison;
241
242                if (file_exists($dest)) {
243                        if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && 
244                                strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= filemtime($dest))
245                        {
246                                if($retour == "http") {
247                                        header('HTTP/1.0 304 Not Modified');
248                                        exit;
249                                } else {
250                                        return $img;
251                                }
252                        }
253                }
254               
255                if (!file_exists($dest) OR filemtime($dest) < filemtime($img) ) {
256                        // Là on fabrique l'image
257                        // et on la recopie vers $dest
258                        //
259                        //cette méthode permet d'accélérer par rapport à SPIP
260                        // parce qu'on connait le nom du fichier à l'avance
261                        // et on fait donc les tests sans déclencher la cavalerie
262                        spip_log("fabrication de l'image responsive $dest","image_responsive");
263                        if ($v) {       
264                                $img_new = image_reduire_net ($img, 0, $taille, $dpr);
265                        } else {
266                                $img_new = image_reduire_net ($img, $taille, 0, $dpr);
267                        }
268                        $img_new = extraire_attribut($img_new, "src");
269                       
270                        copy($img_new, $dest);
271                        if ($img_new != $img) unlink ($img_new);
272                }
273
274                if($retour == "http") {
275                        $extension = str_replace("jpg", "jpeg", $terminaison);
276                        $expires = 60*60*24*14;
277               
278                        if ($xsendfile == 1) { 
279                                $dest = realpath("$dest");
280                                //die($dest);
281                                header("X-Sendfile: $dest");
282                                header("Content-Type: image/".$extension);
283                                exit;
284                        } else {
285                                ob_get_clean();
286                                header("Content-Type: image/".$extension);
287                                header("Pragma: public");
288                                header("Cache-Control: max-age=".$expires);
289                                header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');
290                                header('Content-Length: '.filesize($dest));
291               
292                                header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($dest)).' GMT', true, 200);
293                                readfile($dest);
294                                if (ob_get_level()) {
295                                        ob_end_flush();
296                                }
297                        }
298                } else {
299                        return timestamp($dest);
300                }
301
302        }
303}
Note: See TracBrowser for help on using the repository browser.