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

Last change on this file was 112665, checked in by root, 3 months ago

Bug (grave) quand image déjà à la taille exacte de la réduction. (Merci Dom, Aurel, Jean-Marie)

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