Changeset 79116 in spip-zone


Ignore:
Timestamp:
Dec 3, 2013, 4:26:59 PM (6 years ago)
Author:
cedric@…
Message:

On externalise tout le code Adaptive Images dans une librairie agnostique qui fonctionne de facon autonome fournie par https://github.com/nursit/AdaptiveImages
le plugin se contente de brancher les pipelines SPIP sur les entrees de la librairie

Location:
_plugins_/adaptive_images/trunk
Files:
4 added
2 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/adaptive_images/trunk/adaptive_images_options.php

    r78510 r79116  
    1313if (!defined('_ECRIRE_INC_VERSION')) return;
    1414
    15 if (!defined('_ADAPTIVE_IMAGES_NOJS_PNGGIF_PROGRESSIVE_RENDERING')) define('_ADAPTIVE_IMAGES_NOJS_PNGGIF_PROGRESSIVE_RENDERING',false);
    16 if (!defined('_ADAPTIVE_IMAGES_LOWSRC_JPG_BG_COLOR')) define('_ADAPTIVE_IMAGES_LOWSRC_JPG_BG_COLOR','ffffff');
    17 if (!defined('_ADAPTIVE_IMAGES_LOWSRC_JPG_QUALITY')) define('_ADAPTIVE_IMAGES_LOWSRC_JPG_QUALITY',10);
     15include_once(_DIR_PLUGIN_ADAPTIVE_IMAGES."lib/AdaptiveImages/AdaptiveImages.php");
     16$AdaptiveImage = AdaptiveImages::getInstance();
    1817
     18// utiliser le progressive rendering sur PNG et GIF si pas de JS
     19if (defined('_ADAPTIVE_IMAGES_NOJS_PNGGIF_PROGRESSIVE_RENDERING'))
     20        $AdaptiveImage->nojsPngGifProgressiveRendering = _ADAPTIVE_IMAGES_NOJS_PNGGIF_PROGRESSIVE_RENDERING;
     21// couleur de background pour les images lowsrc
     22if (defined('_ADAPTIVE_IMAGES_LOWSRC_JPG_BG_COLOR'))
     23        $AdaptiveImage->lowsrcJpgBgColor = _ADAPTIVE_IMAGES_LOWSRC_JPG_BG_COLOR;
     24// qualite des images lowsrc
     25if (defined('_ADAPTIVE_IMAGES_LOWSRC_JPG_QUALITY'))
     26        $AdaptiveImage->lowsrcJpgQuality = _ADAPTIVE_IMAGES_LOWSRC_JPG_QUALITY;
    1927// qualite de compression JPG pour les images 1.5x et 2x (on peut comprimer plus)
    20 if (!defined('_ADAPTIVE_IMAGES_15x_JPG_QUALITY')) define('_ADAPTIVE_IMAGES_15x_JPG_QUALITY',65);
    21 if (!defined('_ADAPTIVE_IMAGES_20x_JPG_QUALITY')) define('_ADAPTIVE_IMAGES_20x_JPG_QUALITY',45);
    22 
     28if (defined('_ADAPTIVE_IMAGES_15x_JPG_QUALITY'))
     29        $AdaptiveImage->x15JpgQuality = _ADAPTIVE_IMAGES_15x_JPG_QUALITY;
     30if (defined('_ADAPTIVE_IMAGES_20x_JPG_QUALITY'))
     31        $AdaptiveImage->x20JpgQuality = _ADAPTIVE_IMAGES_20x_JPG_QUALITY;
    2332// Breakpoints de taille d'ecran pour lesquels on generent des images
    24 if (!defined('_ADAPTIVE_IMAGES_DEFAULT_BKPTS')) define('_ADAPTIVE_IMAGES_DEFAULT_BKPTS','160,320,480,640,960,1440');
     33if (defined('_ADAPTIVE_IMAGES_DEFAULT_BKPTS'))
     34        $AdaptiveImage->defaultBkpts = explode(",",_ADAPTIVE_IMAGES_DEFAULT_BKPTS);
    2535// les images 1x sont au maximum en _ADAPTIVE_IMAGES_MAX_WIDTH_1x px de large dans la page
    26 if (!defined('_ADAPTIVE_IMAGES_MAX_WIDTH_1x')) define('_ADAPTIVE_IMAGES_MAX_WIDTH_1x',640);
     36if (defined('_ADAPTIVE_IMAGES_MAX_WIDTH_1x'))
     37        $AdaptiveImage->maxWidth1x = _ADAPTIVE_IMAGES_MAX_WIDTH_1x;
    2738// on ne traite pas les images de largeur inferieure a _ADAPTIVE_IMAGES_MIN_WIDTH_1x px
    28 if (!defined('_ADAPTIVE_IMAGES_MIN_WIDTH_1x')) define('_ADAPTIVE_IMAGES_MIN_WIDTH_1x',320);
    29 
     39if (defined('_ADAPTIVE_IMAGES_MIN_WIDTH_1x'))
     40        $AdaptiveImage->minWidth1x = _ADAPTIVE_IMAGES_MIN_WIDTH_1x;
    3041// Pour les ecrans plus petits, c'est la version mobile qui est fournie (recadree)
    31 if (!defined('_ADAPTIVE_IMAGES_MAX_WIDTH_MOBILE_VERSION')) define('_ADAPTIVE_IMAGES_MAX_WIDTH_MOBILE_VERSION',320);
     42if (defined('_ADAPTIVE_IMAGES_MAX_WIDTH_MOBILE_VERSION'))
     43        $AdaptiveImage->maxWidthMobileVersion = _ADAPTIVE_IMAGES_MAX_WIDTH_MOBILE_VERSION;
    3244
    3345// Pour generer chaque variante d'image uniquement quand elle est demandee pour la premiere fois
     
    4355###
    4456*/
    45 if (!defined('_ADAPTIVE_IMAGES_ON_DEMAND_PRODUCTION')) define('_ADAPTIVE_IMAGES_ON_DEMAND_PRODUCTION',false);
     57define('_ADAPTIVE_IMAGES_ON_DEMAND_PRODUCTION',true);
     58if (defined('_ADAPTIVE_IMAGES_ON_DEMAND_PRODUCTION'))
     59        $AdaptiveImage->onDemandImages = _ADAPTIVE_IMAGES_ON_DEMAND_PRODUCTION;
     60
     61// dossier de stockage des images adaptatives
     62$AdaptiveImage->destDirectory = _DIR_VAR . "adapt-img/";
     63
    4664
    4765
     
    5876function action_adapt_img_dist(){
    5977
    60         $arg = _request('arg');
    61         $mime = "";
    62 
    63         $file = adaptive_images_bkpt_image_from_path($arg, $mime);
    64         if (!$file
    65           OR !$mime){
     78        $AdaptiveImage = AdaptiveImages::getInstance();
     79        try {
     80                $AdaptiveImage->deliverBkptImage(_request('arg'));
     81        }
     82        catch (Exception $e){
    6683                http_status(404);
    6784                include_spip('inc/minipres');
    6885                echo minipres(_T('erreur').' 404',
    69                         _T('medias:info_document_indisponible'),"",true);
    70                 die();
     86                        _T('medias:info_document_indisponible')."<br />".$e->getMessage(),"",true);
    7187        }
    72 
    73         header("Content-Type: ". $mime);
    74         #header("Expires: 3600"); // set expiration time
    75 
    76         if ($cl = filesize($file))
    77                 header("Content-Length: ". $cl);
    78 
    79         readfile($file);
    8088        exit;
    8189}
     
    8391
    8492/** Filtre  ***********************************************************************************************************/
    85 
    8693
    8794/**
     
    9299 * @return mixed
    93100 */
    94 function adaptive_images($texte,$max_width_1x=_ADAPTIVE_IMAGES_MAX_WIDTH_1x){
    95         static $bkpts = array();
    96         if ($max_width_1x AND !isset($bkpts[$max_width_1x])){
    97                 $b = explode(',',_ADAPTIVE_IMAGES_DEFAULT_BKPTS);
    98                 while (count($b) AND end($b)>$max_width_1x) array_pop($b);
    99                 // la largeur maxi affichee
    100                 if (!count($b) OR end($b)<$max_width_1x) $b[] = $max_width_1x;
    101                 $bkpts[$max_width_1x] = $b;
    102         }
    103         $bkpt = (isset($bkpts[$max_width_1x])?$bkpts[$max_width_1x]:null);
    104 
    105         $replace = array();
    106         preg_match_all(",<img\s[^>]*>,Uims",$texte,$matches,PREG_SET_ORDER);
    107         if (count($matches)){
    108                 foreach($matches as $m){
    109                         $ri = adaptive_images_process_img($m[0], $bkpt, $max_width_1x);
    110                         if ($ri!==$m[0]){
    111                                 $replace[$m[0]] = $ri;
    112                         }
    113                 }
    114                 if (count($replace)){
    115                         $texte = str_replace(array_keys($replace),array_values($replace),$texte);
    116                 }
    117         }
    118 
    119         return $texte;
     101function adaptive_images($texte,$max_width_1x=null){
     102        $AdaptiveImage = AdaptiveImages::getInstance();
     103        return $AdaptiveImage->adaptHTMLPart($texte, $max_width_1x);
    120104}
    121105
     
    126110 * @return mixed
    127111 */
    128 function adaptative_images($texte,$max_width_1x=_ADAPTIVE_IMAGES_MAX_WIDTH_1x){
     112function adaptative_images($texte,$max_width_1x=null){
    129113        return adaptive_images($texte,$max_width_1x);
    130114}
     
    200184 */
    201185function adaptive_images_affichage_final($texte){
    202         $adaptive_images_ins = false;
    203186        if ($GLOBALS['html']){
    204187                #spip_timer();
    205                 $texte = adaptative_images($texte);
    206                 if (strpos($texte,"adapt-img-wrapper")!==false){
    207                         // les styles communs a toutes les images responsive en cours de chargement
    208                         $ins = "<style type='text/css'>"."img.adapt-img{opacity:0.70;max-width:100%;height:auto;}"
    209                         ."span.adapt-img-wrapper,span.adapt-img-wrapper:after{display:inline-block;max-width:100%;position:relative;-webkit-background-size:100% auto;background-size:100% auto;background-repeat:no-repeat;line-height:1px;}"
    210                         ."span.adapt-img-wrapper:after{position:absolute;top:0;left:0;right:0;bottom:0;content:\"\"}"
    211                         ."</style>\n";
    212                         // le script qui estime si la rapidite de connexion et pose une class aislow sur <html> si connexion lente
    213                         // et est appele post-chargement pour finir le rendu (rend les images enregistrables par clic-droit aussi)
    214                         $async_style = "html img.adapt-img{opacity:0.01}html span.adapt-img-wrapper:after{display:none;}";
    215                         $length = strlen($texte)+2000; // ~2000 pour le JS qu'on va inserer
    216                         $ins .= "<script type='text/javascript'>/*<![CDATA[*/"
    217                                 ."function adaptImgFix(n){var i=window.getComputedStyle(n.parentNode).backgroundImage.replace(/\W?\)$/,'').replace(/^url\(\W?|/,'');n.src=(i&&i!='none'?i:n.src);}"
    218                                 ."(function(){function hAC(c){(function(H){H.className=H.className+' '+c})(document.documentElement)}"
    219                                 // Android 2 media-queries bad support workaround
    220                                 // muliple rules = multiples downloads : put .android2 on <html>
    221                                 // use with simple css without media-queries and send compressive image
    222                                 ."var android2 = (/android 2[.]/i.test(navigator.userAgent.toLowerCase()));"
    223                                 ."if (android2) {hAC('android2');}\n"
    224                                 // slowConnection detection
    225                                 ."var slowConnection = false;"
    226                                 ."if (typeof window.performance!==\"undefined\"){"
    227                                 ."var perfData = window.performance.timing;"
    228                                 ."var speed = ~~($length/(perfData.responseEnd - perfData.connectStart));" // approx, *1000/1024 to be exact
    229                                 //."console.log(speed);"
    230                                 ."slowConnection = (speed && speed<50);" // speed n'est pas seulement une bande passante car prend en compte la latence de connexion initiale
    231                                 ."}else{"
    232                                 //https://github.com/Modernizr/Modernizr/blob/master/feature-detects/network/connection.js
    233                                 ."var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;"
    234                                 ."if (typeof connection!==\"undefined\") slowConnection = (connection.type == 3 || connection.type == 4 || /^[23]g$/.test(connection.type));"
    235                                 ."}"
    236                                 //."console.log(slowConnection);"
    237                                 ."if(slowConnection) {hAC('aislow');}\n"
    238                                 // injecter un style async apres chargement des images
    239                           // pour masquer les couches superieures (fallback et chargement)
    240                                 ."var adaptImg_onload = function(){"
    241                           ."var sa = document.createElement('style'); sa.type = 'text/css';"
    242                           ."sa.innerHTML = '$async_style';"
    243                           ."var s = document.getElementsByTagName('style')[0]; s.parentNode.insertBefore(sa, s);};"
    244                                 // http://www.webreference.com/programming/javascript/onloads/index.html
    245                                 ."function addLoadEvent(func){var oldol=window.onload;if (typeof oldol != 'function'){window.onload=func;}else{window.onload=function(){if (oldol){oldol();} func();}}}"
    246                                 ."if (typeof jQuery!=='undefined') jQuery(function(){jQuery(window).load(adaptImg_onload)}); else addLoadEvent(adaptImg_onload);"
    247                           ."})();/*]]>*/</script>\n";
    248                         // le noscript alternatif si pas de js pour desactiver le rendu progressif qui ne rend pas bien les PNG transparents
    249                         if (!_ADAPTIVE_IMAGES_NOJS_PNGGIF_PROGRESSIVE_RENDERING)
    250                                 $ins .= "<noscript><style type='text/css'>.png img.adapt-img,.gif img.adapt-img{opacity:0.01}span.adapt-img-wrapper.png:after,span.adapt-img-wrapper.gif:after{display:none;}</style></noscript>";
    251                         // inserer avant le premier <script> ou <link a defaut
    252 
    253                         // regrouper tous les styles adapt-img dans le head
    254                         preg_match_all(",<!--\[if !IE\]><!-->.*(<style[^>]*>.*</style>).*<!--<!\[endif\]-->,Ums",$texte,$matches);
    255                         if (count($matches[1])){
    256                                 $texte = str_replace($matches[1],"",$texte);
    257                                 $ins .= implode("\n",$matches[1]);
    258                         }
    259                         if ($p = strpos($texte,"<link") OR $p = strpos($texte,"<script") OR $p = strpos($texte,"</head"))
    260                                 $texte = substr_replace($texte,"<!--[if !IE]-->$ins\n<!--[endif]-->\n",$p,0);
    261                 }
     188                $AdaptiveImage = AdaptiveImages::getInstance();
     189                $texte = $AdaptiveImage->adaptHTMLPage($texte);
    262190                #var_dump(spip_timer());
    263191        }
     
    265193}
    266194
    267 
    268 /** Production des images  ********************************************************************************************/
    269 
    270 /**
    271  *
    272  * @param string $img
    273  * @param array $rwd_images
    274  *   tableau
    275  *     width => file
    276  * @param int $width
    277  * @param int $height
    278  * @param string $extension
    279  * @param int $max_width_1x
    280  * @return string
    281  */
    282 function adaptive_images_markup($img, $rwd_images, $width, $height, $extension, $max_width_1x=_ADAPTIVE_IMAGES_MAX_WIDTH_1x){
    283         $class = extraire_attribut($img,"class");
    284         if (strpos($class,"adapt-img")!==false) return $img;
    285         ksort($rwd_images);
    286         $cid = "c".crc32(serialize($rwd_images));
    287         $style = "";
    288         if ($class) $class = " $class";
    289         $class = "$cid$class";
    290         $img = inserer_attribut($img,"class","adapt-img-ie $class");
    291 
    292         // image de fallback fournie ?
    293         if (isset($rwd_images['fallback'])){
    294                 $fallback_file = $rwd_images['fallback'];
    295                 unset($rwd_images['fallback']);
    296         }
    297         // sinon on affiche la plus petite image
    298         if (!$fallback_file){
    299                 $fallback_file = reset($rwd_images);
    300                 $fallback_file = $fallback_file['10x'];
    301         }
    302         // embarquer le fallback en DATA URI si moins de 32ko (eviter une page trop grosse)
    303         if (!isset($GLOBALS['tables_mime']))
    304                 include_spip("base/typedoc");
    305         $fallback_file = adaptive_images_filtre_embarque_fichier($fallback_file,"",32000);
    306 
    307         $prev_width = 0;
    308         $medias = array();
    309         $lastw = array_keys($rwd_images);
    310         $lastw = end($lastw);
    311         $wandroid = 0;
    312         foreach ($rwd_images as $w=>$files){
    313                 if ($w==$lastw) {$islast = true;}
    314                 if ($w<=_ADAPTIVE_IMAGES_MAX_WIDTH_MOBILE_VERSION) $wandroid = $w;
    315                 // il faut utiliser une clause min-width and max-width pour que les regles soient exlusives
    316                 if ($prev_width<$max_width_1x){
    317                         $hasmax = (($islast OR $w>=$max_width_1x)?false:true);
    318                         $mw = ($prev_width?"and (min-width:{$prev_width}px)":"").($hasmax?" and (max-width:{$w}px)":"");
    319                         $htmlsel = "html:not(.android2)";
    320                         $htmlsel = array(
    321                                 '10x' => "$htmlsel",
    322                                 '15x' => "$htmlsel:not(.aislow)",
    323                                 '20x' => "$htmlsel:not(.aislow)",
    324                         );
    325                 }
    326                 $mwdpi = array(
    327                         '10x' => "screen $mw",
    328                         '15x' => "screen and (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 1.99) $mw,screen and (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 1.99) $mw",
    329                         '20x' => "screen and (-webkit-min-device-pixel-ratio: 2) $mw,screen and (min--moz-device-pixel-ratio: 2) $mw",
    330                 );
    331                 foreach($files as $kx=>$file){
    332                         if (isset($mwdpi[$kx])){
    333                                 // $file = "filedelay.api/5/$file"; // debug : injecter une tempo dans le chargement de l'image pour tester l'enrichissement progressif
    334                                 //$file = $file."?rwd"; // debug  : etre sur qu'on charge bien l'image issue des medias queries
    335                                 $mw = $mwdpi[$kx];
    336                                 $not = $htmlsel[$kx];
    337                                 $medias[$mw] = "@media $mw{{$not} span.$cid,{$not} span.$cid:after{background-image:url($file);}}";
    338                         }
    339                 }
    340                 $prev_width = $w+1;
    341         }
    342 
    343         // Une regle CSS simple pour android qui (selon les versions/nav) n'arrive pas a s'y retrouver dans les media-queries
    344         // et charge toutes les images
    345         // donc une seule image, JPG 320 - 1.5x (compromis)
    346         if ($wandroid){
    347                 $file = $rwd_images[$wandroid]['15x'];
    348                 $medias['android2'] = "html.android2 span.$cid,html.android2 span.$cid:after{background-image:url($file);}";
    349         }
    350 
    351         // Media Queries
    352         $style .= implode("",$medias);
    353 
    354         $out = "<!--[if IE]>$img<![endif]-->\n";
    355         $img = inserer_attribut($img,"src",$fallback_file);
    356         $img = inserer_attribut($img,"class","adapt-img $class");
    357         $img = inserer_attribut($img,"onmousedown","adaptImgFix(this)");
    358         // $img = inserer_attribut($img,"onkeydown","adaptImgFix(this)"); // usefull ?
    359         $out .= "<!--[if !IE]><!--><span class=\"adapt-img-wrapper $cid $extension\">$img</span>\n<style>$style</style><!--<![endif]-->";
    360 
    361         return $out;
    362 }
    363 
    364 /**
    365  * Embarquer sous forme URI Scheme un fichier
    366  * fix temporaire pour filtre_embarque_fichier de compresseur_fonctions qui fait une requete SQL a chaque hit
    367  * on utilise la globale tables_mime si chargee en memoire (a faire par l'appelant)
    368  *
    369  * Une URI Scheme est de la forme data:xxx/yyy;base64,....
    370  *
    371  * Experimental
    372  *
    373  * @filtre embarque_fichier
    374  *
    375  * @staticvar array $mime
    376  *     Couples (extension de fichier => type myme)
    377  * @param string $src
    378  *     Chemin du fichier
    379  * @param string $base
    380  *     Le chemin de base à partir duquel chercher $src
    381  * @param int $maxsize
    382  *     Taille maximale des fichiers à traiter
    383  * @return string
    384  *     URI Scheme du fichier si la compression est faite,
    385  *     URL du fichier sinon (la source)
    386  */
    387 function adaptive_images_filtre_embarque_fichier ($src, $base="", $maxsize = 4096) {
    388         static $mime = array();
    389         $extension = substr(strrchr($src,'.'),1);
    390         $filename = $base . $src;
    391 
    392         if (!file_exists($filename)
    393                 OR filesize($filename)>$maxsize
    394                 OR !lire_fichier($filename, $contenu))
    395                 return $src;
    396 
    397         if (!isset($mime[$extension])){
    398                 if (isset($GLOBALS['tables_mime']) AND isset($GLOBALS['tables_mime'][$extension]))
    399                         $mime[$extension] = $GLOBALS['tables_mime'][$extension];
    400         }
    401         if (!isset($mime[$extension])){
    402                 if (!function_exists("sql_getfetsel"))
    403                         include_spip("base/abstract_sql");
    404                 $mime[$extension] = sql_getfetsel('mime_type','spip_types_documents','extension='.sql_quote($extension));
    405         }
    406 
    407         $base64 = base64_encode($contenu);
    408         $encoded = 'data:'.$mime[$extension].';base64,'.$base64;
    409 
    410         return $encoded;
    411 }
    412 
    413 /**
    414  * extrait les infos d'une image,
    415  * calcule les variantes en fonction des breakpoints
    416  * si l'image est de taille superieure au plus petit breakpoint
    417  * et renvoi un markup responsive si il y a lieu
    418  *
    419  * @param string $img
    420  * @param array $bkpt
    421  * @param int $max_width_1x
    422  * @return string
    423  */
    424 function adaptive_images_process_img($img, $bkpt = null, $max_width_1x=_ADAPTIVE_IMAGES_MAX_WIDTH_1x){
    425         if (!$img) return $img;
    426         if (strpos($img,"adapt-img")!==false)
    427                 return $img;
    428         if (is_null($bkpt) OR !is_array($bkpt))
    429                 $bkpt = explode(',',_ADAPTIVE_IMAGES_DEFAULT_BKPTS);
    430 
    431         if (!function_exists("taille_image"))
    432                 include_spip("inc/filtres");
    433         if (!function_exists("image_reduire"))
    434                 include_spip("inc/filtres_images_mini");
    435         if (!function_exists("image_aplatir"))
    436                 include_spip("filtres/images_transforme");
    437 
    438         list($h,$w) = taille_image($img);
    439         if (!$w OR $w<=_ADAPTIVE_IMAGES_MIN_WIDTH_1x) return $img;
    440 
    441         $src = trim(extraire_attribut($img, 'src'));
    442         if (strlen($src) < 1){
    443                 $src = $img;
    444                 $img = "<img src='$src' />";
    445         }
    446         $src_mobile = extraire_attribut($img, 'data-src-mobile');
    447 
    448         // on ne touche pas aux data:uri
    449         if (strncmp($src,"data:",5)==0)
    450                 return $img;
    451 
    452         $images = array();
    453         if ($w<end($bkpt))
    454                 $images[$w] = array(
    455                         '10x'=>$src,
    456                         '15x'=>$src,
    457                         '20x'=>$src,
    458                 );
    459         $src=preg_replace(',[?][0-9]+$,','',$src);
    460 
    461         // si on arrive pas a le lire, on ne fait rien
    462         if (!file_exists($src))
    463                 return $img;
    464 
    465         $parts = pathinfo($src);
    466         $extension = $parts['extension'];
    467 
    468         // on ne touche pas aux GIF animes !
    469         if ($extension=="gif" AND adaptive_images_is_animated_gif($src))
    470                 return $img;
    471 
    472         // calculer les variantes d'image sur les breakpoints
    473         $fallback = $src;
    474         $wfallback = $w;
    475         $dpi = array('10x'=>1,'15x'=>1.5,'20x'=>2);
    476         foreach($bkpt as $wk){
    477                 if ($wk>$w) break;
    478                 $is_mobile = (($src_mobile AND $wk<=_ADAPTIVE_IMAGES_MAX_WIDTH_MOBILE_VERSION)?true:false);
    479                 foreach($dpi as $k=>$x){
    480                         $wkx = intval(round($wk * $x));
    481                         if ($wkx>$w)
    482                                 $images[$wk][$k] = $src;
    483                         else {
    484                                 $images[$wk][$k] = adaptive_images_bkpt_image($is_mobile?$src_mobile:$src,$wk,$wkx,$k,$extension);
    485                         }
    486                 }
    487                 if ($wk<=$max_width_1x AND ($is_mobile OR !$src_mobile)) {
    488                         $fallback = $images[$wk]['10x'];
    489                         $wfallback = $wk;
    490                 }
    491         }
    492 
    493         // l'image de fallback en jpg tres compresse
    494         if (function_exists("image_aplatir")){
    495                 // image de fallback : la plus grande en jpg tres compresse ou la version mobile en jpg tres compresse
    496                 if ($wk>$w&&$w<$max_width_1x){
    497                         $fallback = $images[$w]['10x'];
    498                         $wfallback = $w;
    499                 }
    500 
    501                 // l'image n'a peut etre pas ete produite car _ADAPTIVE_IMAGES_ON_DEMAND_PRODUCTION = true
    502                 // on la genere immediatement car on en a besoin
    503                 if (!file_exists($fallback)){
    504                         $mime = "";
    505                         adaptive_images_bkpt_image_from_path($fallback, $mime);
    506                 }
    507                 // la qualite est reduite si la taille de l'image augmente, pour limiter le poids de l'image
    508                 // regle de 3 au feeling, _ADAPTIVE_IMAGES_LOWSRC_JPG_QUALITY correspond a une image de 450kPx
    509                 // et on varie dans +/-50% de _ADAPTIVE_IMAGES_LOWSRC_JPG_QUALITY
    510                 $q = round(_ADAPTIVE_IMAGES_LOWSRC_JPG_QUALITY-((min($max_width_1x,$wfallback)*$h/$w*min($max_width_1x,$wfallback))/75000-6));
    511                 $q = min($q,round(_ADAPTIVE_IMAGES_LOWSRC_JPG_QUALITY)*1.5);
    512                 $q = max($q,round(_ADAPTIVE_IMAGES_LOWSRC_JPG_QUALITY)*0.5);
    513                 $fallback = image_aplatir($fallback,'jpg',_ADAPTIVE_IMAGES_LOWSRC_JPG_BG_COLOR,$q);
    514                 $images["fallback"] = extraire_attribut($fallback,"src");
    515         }
    516 
    517         // l'image est reduite a la taille maxi (version IE)
    518         $img = image_reduire($img,$max_width_1x,10000);
    519         // generer le markup
    520         return adaptive_images_markup($img,$images,$w, $h, $extension, $max_width_1x);
    521 }
    522 
    523 /**
    524  * Preparer une image pour un breakpoint/resolution
    525  * @param string $src
    526  *   image source
    527  * @param int $wkpt
    528  *   largeur du breakpoint (largeur d'affichage) pour lequel l'image est produite
    529  * @param int $wx
    530  *   largeur en px de l'image reelle
    531  * @param string $x
    532  *   resolution 10x 15x 20x
    533  * @param string $extension
    534  *   extenstion
    535  * @param bool $force
    536  *   produire l'image immediatement si elle n'existe pas ou est trop vieille
    537  * @return string
    538  *   nom du fichier resultat
    539  */
    540 function adaptive_images_bkpt_image($src, $wkpt, $wx, $x, $extension, $force=false){
    541         $dest = _DIR_VAR."adapt-img/$wkpt/$x/$src";
    542         if (($exist=file_exists($dest)) AND filemtime($dest)>=filemtime($src))
    543                 return $dest;
    544 
    545         $force = ($force?true:!_ADAPTIVE_IMAGES_ON_DEMAND_PRODUCTION);
    546 
    547         // si le fichier existe mais trop vieux et que l'on ne veut pas le produire immediatement : supprimer le vieux fichier
    548         // ainsi le hit passera par la regexp et tommbera sur l'action adapt_img qui le produira
    549         if ($exist AND !$force)
    550                 @unlink($dest);
    551 
    552         if (!$force)
    553                 return $dest;
    554 
    555         // creer l'arbo
    556         $dirs = explode("/",$dest);
    557         $d = "";
    558         while(count($dirs)>1
    559                 AND (
    560                   is_dir($f="$d".($sd=array_shift($dirs)))
    561                   OR
    562                   $f = sous_repertoire($d,$sd)
    563                 )
    564         ) $d = $f;
    565 
    566         $i = image_reduire($src,$wx,10000);
    567 
    568         if (in_array($extension,array('jpg','jpeg')) AND $x!='10x')
    569                 $i = image_aplatir($i,'jpg',_ADAPTIVE_IMAGES_LOWSRC_JPG_BG_COLOR,constant('_ADAPTIVE_IMAGES_'.$x.'_JPG_QUALITY'));
    570         $i = extraire_attribut($i,"src");
    571         @copy($i,$dest);
    572 
    573         return file_exists($dest)?$dest:$src;
    574 }
    575 
    576 /**
    577  * Produire une image d'apres son URL
    578  * utilise par ?action=adapt_img pour la premiere production a la volee
    579  * ou depuis adaptive_images_process_img() si on a besoin de l'image tout de suite
    580  *
    581  * @param string $arg
    582  * @param string $mime
    583  * @return string
    584  */
    585 function adaptive_images_bkpt_image_from_path($arg,&$mime){
    586         $base = _DIR_VAR."adapt-img/";
    587         if (strncmp($arg,$base,strlen($base))==0)
    588                 $arg = substr($arg,strlen($base));
    589 
    590         $arg = explode("/",$arg);
    591         $wkpt = intval(array_shift($arg));
    592         $x = array_shift($arg);
    593         $src = implode("/",$arg);
    594 
    595         $parts = pathinfo($src);
    596         $extension = strtolower($parts['extension']);
    597         include_spip("base/typedoc");
    598         if ($extension=="jpeg") $extension = "jpg";
    599         $mime = (isset($GLOBALS['tables_mime'][$extension])?$GLOBALS['tables_mime'][$extension]:'');
    600         $dpi = array('10x'=>1,'15x'=>1.5,'20x'=>2);
    601 
    602         if (!$wkpt
    603           OR !isset($dpi[$x])
    604           OR !file_exists($src)
    605           OR !$mime){
    606                 return "";
    607         }
    608         $wx = intval(round($wkpt * $dpi[$x]));
    609 
    610         if (!function_exists("taille_image"))
    611                 include_spip("inc/filtres");
    612         if (!function_exists("image_reduire"))
    613                 include_spip("inc/filtres_images_mini");
    614         if (!function_exists("image_aplatir"))
    615                 include_spip("filtres/images_transforme");
    616 
    617         $file = adaptive_images_bkpt_image($src, $wkpt, $wx, $x, $extension, true);
    618         return $file;
    619 }
    620 
    621 /**
    622  * Detecter un GIF anime
    623  * http://it.php.net/manual/en/function.imagecreatefromgif.php#59787
    624  *
    625  * @param string $filename
    626  * @return bool
    627  */
    628 function adaptive_images_is_animated_gif($filename){
    629         $filecontents = file_get_contents($filename);
    630 
    631         $str_loc = 0;
    632         $count = 0;
    633         while ($count<2) # There is no point in continuing after we find a 2nd frame
    634         {
    635 
    636                 $where1 = strpos($filecontents, "\x00\x21\xF9\x04", $str_loc);
    637                 if ($where1===FALSE){
    638                         break;
    639                 } else {
    640                         $str_loc = $where1+1;
    641                         $where2 = strpos($filecontents, "\x00\x2C", $str_loc);
    642                         if ($where2===FALSE){
    643                                 break;
    644                         } else {
    645                                 if ($where1+8==$where2){
    646                                         $count++;
    647                                 }
    648                                 $str_loc = $where2+1;
    649                         }
    650                 }
    651         }
    652 
    653         if ($count>1){
    654                 return (true);
    655 
    656         } else {
    657                 return (false);
    658         }
    659 }
    660195?>
  • _plugins_/adaptive_images/trunk/paquet.xml

    r78510 r79116  
    22        prefix="adaptive_images"
    33        categorie="multimedia"
    4         version="1.2.1"
     4        version="1.3.0"
    55        etat="stable"
    66        compatibilite="[3.0.0;3.0.*]"
Note: See TracChangeset for help on using the changeset viewer.