Newer
Older
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
* *
* Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
* Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
\***************************************************************************/
if (!defined("_ECRIRE_INC_VERSION")) return;
cerdic
a validé
include_spip('inc/filtres'); // par precaution
cerdic
a validé
// http://doc.spip.org/@cherche_image_nommee
function cherche_image_nommee($nom, $formats = array ('gif', 'jpg', 'png')) {
if (ereg("^" . _DIR_IMG, $nom)) {
$nom = substr($nom,strlen(_DIR_IMG));
} else if (ereg("^" . _DIR_IMG_PACK, $nom)) {
$nom = substr($nom,strlen(_DIR_IMG_PACK));
} else if (ereg("^" . _DIR_IMG_ICONES_DIST, $nom)) {
$nom = substr($nom,strlen(_DIR_IMG_ICONES_DIST));
}
$pos = strrpos($nom, "/");
if ($pos > 0) {
$chemin = substr($nom, 0, $pos+1);
$nom = substr($nom, $pos+1);
} else {
$chemin = "";
}
reset($formats);
while (list(, $format) = each($formats)) {
if (@file_exists(_DIR_IMG . "$chemin$nom.$format")){
return array((_DIR_IMG . $chemin), $nom, $format);
} else if (@file_exists(_DIR_IMG_PACK . "$chemin$nom.$format")){
return array((_DIR_IMG_PACK . $chemin), $nom, $format);
} else if (@file_exists(_DIR_IMG_ICONES_DIST . "$chemin$nom.$format")){
return array((_DIR_IMG_ICONES_DIST . $chemin), $nom, $format);
}
cerdic
a validé
}
}
// Fonctions de traitement d'image
// uniquement pour GD2
// http://doc.spip.org/@image_valeurs_trans
function image_valeurs_trans($img, $effet, $forcer_format = false) {
if (strlen($img)==0) return false;
cerdic
a validé
$source = extraire_attribut($img, 'src');
if (($p=strpos($source,'?'))!==FALSE)
$source=substr($source,0,$p);
if (strlen($source) < 1){
$source = $img;
$img = "<img src='$source' />";
}
$fichier = $source;
// les protocoles web prennent au moins 3 lettres
if (preg_match(';^(\w{3,7}://);', $source)){
include_spip("inc/distant");
$fichier = fichier_copie_locale($source);
}
cerdic
a validé
if (!file_exists($fichier)) return false;
if (preg_match(",^(?>.*)(?<=\.(gif|jpg|png)),", $fichier, $regs)) {
$terminaison = $regs[1];
$terminaison_dest = $terminaison;
if ($terminaison == "gif") $terminaison_dest = "png";
} else return false;
if ($forcer_format) $terminaison_dest = $forcer_format;
$term_fonction = $terminaison;
if ($term_fonction == "jpg") $term_fonction = "jpeg";
$term_fonction_dest = $terminaison_dest;
if ($term_fonction_dest == "jpg") $term_fonction_dest = "jpeg";
cerdic
a validé
$nom_fichier = substr($fichier, 0, strlen($fichier) - 4);
$fichier_dest = $nom_fichier;
list ($ret["hauteur"],$ret["largeur"]) = taille_image($img);
// cas general :
// on a un dossier cache commun et un nom de fichier qui varie avec l'effet
// cas particulier de reduire :
// un cache par dimension, et le nom de fichier est conserve, suffixe par la dimension aussi
$cache = "cache-gd2";
if (substr($effet,0,7)=='reduire') {
list(,$maxWidth,$maxHeight) = explode('-',$effet);
list ($destWidth,$destHeight) = image_ratio($ret['largeur'], $ret['hauteur'], $maxWidth, $maxHeight);
$ret['largeur_dest'] = $destWidth;
$ret['hauteur_dest'] = $destHeight;
$effet = "L{$destWidth}xH$destHeight";
$cache = "cache-vignettes";
$fichier_dest = basename($fichier_dest).'-'.substr(md5("$fichier_dest-$effet"),0,5);
if (($ret['largeur']<=$maxWidth)&&($ret['hauteur']<=$maxHeight))
$terminaison_dest = $terminaison; // on garde la terminaison initiale car image simplement copiee
$cache = sous_repertoire(_DIR_VAR, $cache);
$cache = sous_repertoire($cache, $effet);
}
else {
$fichier_dest = md5("$fichier_dest-$effet");
$cache = sous_repertoire(_DIR_VAR, $cache);
}
$fichier_dest = $cache . $fichier_dest . "." .$terminaison_dest;
if (($date_src = @filemtime($fichier)) < @filemtime($fichier_dest)) {
$creer = false;
}
$ret["fichier"] = $fichier;
cerdic
a validé
$ret["fonction_imagecreatefrom"] = "imagecreatefrom".$term_fonction;
$ret["fonction_image"] = "image".$term_fonction_dest;
$ret["fichier_dest"] = $fichier_dest;
cerdic
a validé
$ret["format_source"] = $terminaison;
$ret["format_dest"] = $terminaison_dest;
$ret["date_src"] = $date_src;
$ret["creer"] = $creer;
cerdic
a validé
$ret["class"] = extraire_attribut($img, 'class');
$ret["alt"] = extraire_attribut($img, 'alt');
$ret["style"] = extraire_attribut($img, 'style');
cerdic
a validé
$ret["tag"] = $img;
// Transforme une image a palette indexee (256 couleurs max) en "vraies" couleurs RGB
// http://doc.spip.org/@imagepalettetotruecolor
function imagepalettetotruecolor(&$img) {
if (!imageistruecolor($img) AND function_exists(imagecreatetruecolor)) {
$w = imagesx($img);
$h = imagesy($img);
$img1 = imagecreatetruecolor($w,$h);
imagecopy($img1,$img,0,0,0,0,$w,$h);
$img = $img1;
}
}
function image_tag_changer_taille($tag,$width,$height,$style=false){
if ($style===false) $style = extraire_attribut($tag,'style');
// enlever le width et height du style
$style = preg_replace(",(^|;)\s*(width|height)\s*:\s*[^;]+,ims","",$style);
if ($style AND $style{0}==';') $style=substr($style,1);
// mettre des attributs de width et height sur les images,
// ca accelere le rendu du navigateur
// ca permet aux navigateurs de reserver la bonne taille
// quand on a desactive l'affichage des images.
$tag = inserer_attribut($tag,'width',$width);
$tag = inserer_attribut($tag,'height',$height);
$style = "height:".$height."px;width:".$width."px;".$style;
// attributs deprecies. Transformer en CSS
if ($espace = extraire_attribut($tag, 'hspace')){
$style = "margin:${espace}px;".$style;
$tag = inserer_attribut($tag,'hspace','');
}
$tag = inserer_attribut($tag,'style',$style);
return $tag;
}
cerdic
a validé
// function d'ecriture du tag img en sortie des filtre image
// reprend le tag initial et surcharge les tags modifies
function image_ecrire_tag($valeurs,$surcharge){
cerdic
a validé
$tag = str_replace(">","/>",str_replace("/>",">",$valeurs['tag'])); // fermer les tags img pas bien fermes;
// le style
$style = $valeurs['style'];
if (isset($surcharge['style'])){
$style = $surcharge['style'];
unset($surcharge['style']);
}
// traiter specifiquement la largeur et la hauteur
$width = $valeurs['largeur'];
if (isset($surcharge['width'])){
$width = $surcharge['width'];
unset($surcharge['width']);
}
$height = $valeurs['hauteur'];
if (isset($surcharge['height'])){
$height = $surcharge['height'];
cerdic
a validé
unset($surcharge['height']);
}
$tag = image_tag_changer_taille($tag,$width,$height,$style);
// traiter specifiquement le src qui peut etre repris dans un onmouseout
// on remplace toute les ref a src dans le tag
$src = extraire_attribut($tag,'src');
if (isset($surcharge['src'])){
$tag = str_replace($src,$surcharge['src'],$tag);
$src = $surcharge['src'];
unset($surcharge['src']);
}
cerdic
a validé
// regarder la class pour gerer le 'format_png' en fonction du format de l'image
// (et le remettre sinon)
$class = $valeurs['class'];
cerdic
a validé
if (isset($surcharge['class'])){
$class = $surcharge['class'];
unset($surcharge['class']);
}
$is_png = preg_match(',[.]png($|\?),i',$src);
$p = strpos($class,'format_png');
if ($is_png && $p===FALSE) $class .= " format_png";
if (!$is_png && $p!==FALSE) $class = preg_replace(",\s*format_png,","",$class);
$tag = inserer_attribut($tag,'class',$class);
cerdic
a validé
if (count($surcharge))
foreach($surcharge as $attribut=>$valeur)
$tag = inserer_attribut($tag,$attribut,$valeur);
cerdic
a validé
return $tag;
}
cerdic
a validé
// selectionner les images qui vont subir une transformation sur un critere de taille
// ls images exclues sont marquees d'une class no_image_filtrer qui bloque les filtres suivants
// dans la fonction image_filtrer
// http://doc.spip.org/@image_select
function image_select($img,$width_min=0, $height_min=0, $width_max=10000, $height_max=1000){
if (!$img) return $img;
list ($h,$l) = taille_image($img);
$select = true;
if ($l<$width_min OR $l>$width_max OR $h<$height_min OR $h>$height_max)
$select = false;
$class = extraire_attribut($img,'class');
$p = strpos($class,'no_image_filtrer');
if (($select==false) AND ($p===FALSE)){
$class .= " no_image_filtrer";
$img = inserer_attribut($img,'class',$class);
}
if (($select==true) AND ($p!==FALSE)){
$class = preg_replace(",\s*no_image_filtrer,","",$class);
$img = inserer_attribut($img,'class',$class);
}
return $img;
}
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
function image_creer_vignette($valeurs, $maxWidth, $maxHeight, $process='AUTO', $force=false, $test_cache_only = false) {
// ordre de preference des formats graphiques pour creer les vignettes
// le premier format disponible, selon la methode demandee, est utilise
$image = $valeurs['fichier'];
$format = $valeurs['format_source'];
$destdir = dirname($valeurs['fichier_dest']);
$destfile = basename($valeurs['fichier_dest'],".".$valeurs["format_dest"]);
if ($format == 'jpg')
$formats_sortie = array('jpg','png','gif');
else // les gif sont passes en png preferentiellement pour etre homogene aux autres filtres images
$formats_sortie = array('png','jpg','gif');
if (($process == 'AUTO') AND isset($GLOBALS['meta']['image_process']))
$process = $GLOBALS['meta']['image_process'];
// liste des formats qu'on sait lire
$img = isset($GLOBALS['meta']['formats_graphiques'])
? in_array($format,explode(',',$GLOBALS['meta']['formats_graphiques']))
: false;
// si le doc n'est pas une image, refuser
if (!$force AND !$img) return;
$destination = "$destdir/$destfile";
// chercher un cache
$vignette = '';
foreach (array('gif','jpg','png') as $fmt)
if (@file_exists($destination.'.'.$fmt)) {
$vignette = $destination.'.'.$fmt;
if ($force) @unlink($vignette);
}
if ($test_cache_only AND !$vignette) return;
// utiliser le cache ?
if (!$test_cache_only)
if ($force OR !$vignette OR (@filemtime($vignette) < @filemtime($image))) {
$creation = true;
// calculer la taille
if (($srcWidth=$valeurs['largeur']) && ($srcHeight=$valeurs['hauteur'])){
if (!($destWidth=$valeurs['largeur_dest']) || !($destHeight=$valeurs['hauteur_dest']))
list ($destWidth,$destHeight) = image_ratio($valeurs['largeur'], $valeurs['hauteur'], $maxWidth, $maxHeight);
}
elseif ($process == 'convert' OR $process == 'imagick') {
$destWidth = $maxWidth;
$destHeight = $maxHeight;
} else {
spip_log("echec $process sur $image");
return;
}
// Si l'image est de la taille demandee (ou plus petite), simplement
// la retourner
if ($srcWidth
AND $srcWidth <= $maxWidth AND $srcHeight <= $maxHeight) {
$vignette = $destination.'.'.$format;
@copy($image, $vignette);
}
// imagemagick en ligne de commande
else if ($process == 'convert') {
define('_CONVERT_COMMAND', 'convert');
define ('_RESIZE_COMMAND', _CONVERT_COMMAND.' -quality 85 -resize %xx%y! %src %dest');
$format = $formats_sortie[0];
$vignette = $destination.".".$format;
$commande = str_replace(
array('%x', '%y', '%src', '%dest'),
array(
$destWidth,
$destHeight,
escapeshellcmd($image),
escapeshellcmd($vignette)
),
_RESIZE_COMMAND);
spip_log($commande);
exec($commande);
if (!@file_exists($vignette)) {
spip_log("echec convert sur $vignette");
return; // echec commande
}
}
else
// imagick (php4-imagemagick)
if ($process == 'imagick') {
$format = $formats_sortie[0];
$vignette = "$destination.".$format;
$handle = imagick_readimage($image);
imagick_resize($handle, $destWidth, $destHeight, IMAGICK_FILTER_LANCZOS, 0.75);
imagick_write($handle, $vignette);
if (!@file_exists($vignette)) {
spip_log("echec imagick sur $vignette");
return;
}
}
else
// netpbm
if ($process == "netpbm") {
define('_PNMSCALE_COMMAND', 'pnmscale'); // chemin a changer dans mes_options
if (_PNMSCALE_COMMAND == '') return;
$format_sortie = "jpg";
$vignette = $destination.".".$format_sortie;
$pnmtojpeg_command = str_replace("pnmscale", "pnmtojpeg", _PNMSCALE_COMMAND);
if ($format == "jpg") {
$jpegtopnm_command = str_replace("pnmscale", "jpegtopnm", _PNMSCALE_COMMAND);
exec("$jpegtopnm_command $image | "._PNMSCALE_COMMAND." -width $destWidth | $pnmtojpeg_command > $vignette");
if (!($s = @filesize($vignette)))
@unlink($vignette);
if (!@file_exists($vignette)) {
spip_log("echec netpbm-jpg sur $vignette");
return;
}
} else if ($format == "gif") {
$giftopnm_command = str_replace("pnmscale", "giftopnm", _PNMSCALE_COMMAND);
exec("$giftopnm_command $image | "._PNMSCALE_COMMAND." -width $destWidth | $pnmtojpeg_command > $vignette");
if (!($s = @filesize($vignette)))
@unlink($vignette);
if (!@file_exists($vignette)) {
spip_log("echec netpbm-gif sur $vignette");
return;
}
} else if ($format == "png") {
$pngtopnm_command = str_replace("pnmscale", "pngtopnm", _PNMSCALE_COMMAND);
exec("$pngtopnm_command $image | "._PNMSCALE_COMMAND." -width $destWidth | $pnmtojpeg_command > $vignette");
if (!($s = @filesize($vignette)))
@unlink($vignette);
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
if (!@file_exists($vignette)) {
spip_log("echec netpbm-png sur $vignette");
return;
}
}
}
// gd ou gd2
else if ($process == 'gd1' OR $process == 'gd2') {
if (_IMG_GD_MAX_PIXELS && $srcWidth*$srcHeight>_IMG_GD_MAX_PIXELS){
spip_log("vignette gd1/gd2 impossible : ".$srcWidth*$srcHeight."pixels");
return;
}
// Choisir le format destination
// - on sauve de preference en JPEG (meilleure compression)
// - pour le GIF : les GD recentes peuvent le lire mais pas l'ecrire
# bug : gd_formats contient la liste des fichiers qu'on sait *lire*,
# pas *ecrire*
$gd_formats = $GLOBALS['meta']["gd_formats"];
foreach ($formats_sortie as $fmt) {
if (ereg($fmt, $gd_formats)) {
if ($format <> "gif" OR function_exists('ImageGif'))
$destFormat = $fmt;
break;
}
}
if (!$destFormat) {
spip_log("pas de format pour $image");
return;
}
# calcul de memoire desactive car pas fiable
#$memoryNeeded = round(($srcsize[0] * $srcsize[1] * $srcsize['bits'] * $srcsize['channels'] / 8 + 65536) * 1.65);
#spip_log("GD : memory need $memoryNeeded");
#if (function_exists('memory_get_usage'))
#spip_log("GD : memory usage ".memory_get_usage());
#spip_log("GD : memory_limit ".ini_get('memory_limit'));
#if (function_exists('memory_get_usage') && memory_get_usage() + $memoryNeeded > (integer) ini_get('memory_limit') * 1048576){
# spip_log("vignette gd1/gd2 impossible : memoire insuffisante $memoryNeeded necessaire");
# return;
#}
#else
{
$fonction_imagecreatefrom = $valeurs['fonction_imagecreatefrom'];
$srcImage = $fonction_imagecreatefrom($image);
if (!$srcImage) {
spip_log("echec gd1/gd2");
return;
}
// Initialisation de l'image destination
if ($process == 'gd2' AND $destFormat != "gif")
$destImage = ImageCreateTrueColor($destWidth, $destHeight);
if (!$destImage)
$destImage = ImageCreate($destWidth, $destHeight);
// Recopie de l'image d'origine avec adaptation de la taille
$ok = false;
if (($process == 'gd2') AND function_exists('ImageCopyResampled')) {
if ($format == "gif") {
// Si un GIF est transparent,
// fabriquer un PNG transparent
$transp = imagecolortransparent($srcImage);
if ($transp > 0) $destFormat = "png";
}
if ($destFormat == "png") {
// Conserver la transparence
if (function_exists("imageAntiAlias")) imageAntiAlias($destImage,true);
@imagealphablending($destImage, false);
@imagesavealpha($destImage,true);
}
$ok = @ImageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
}
if (!$ok)
$ok = ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
}
// Sauvegarde de l'image destination
$vignette = "$destination.$destFormat";
$format = $destFormat;
if ($destFormat == "jpg")
ImageJPEG($destImage, $vignette, 85);
else if ($destFormat == "gif")
ImageGIF($destImage, $vignette);
else if ($destFormat == "png")
ImagePNG($destImage, $vignette);
if ($srcImage)
ImageDestroy($srcImage);
ImageDestroy($destImage);
}
}
$size = @getimagesize($vignette);
// Gaffe: en safe mode, pas d'acces a la vignette,
// donc risque de balancer "width='0'", ce qui masque l'image sous MSIE
if ($size[0] < 1) $size[0] = $destWidth;
if ($size[1] < 1) $size[1] = $destHeight;
$retour['width'] = $largeur = $size[0];
$retour['height'] = $hauteur = $size[1];
$retour['fichier'] = $vignette;
$retour['format'] = $format;
$retour['date'] = @filemtime($vignette);
// renvoyer l'image
return $retour;
}
// Calculer le ratio
// http://doc.spip.org/@image_ratio
function image_ratio ($srcWidth, $srcHeight, $maxWidth, $maxHeight) {
$ratioWidth = $srcWidth/$maxWidth;
$ratioHeight = $srcHeight/$maxHeight;
if ($ratioWidth <=1 AND $ratioHeight <=1) {
$destWidth = $srcWidth;
$destHeight = $srcHeight;
} else if ($ratioWidth < $ratioHeight) {
$destWidth = $srcWidth/$ratioHeight;
$destHeight = $maxHeight;
}
else {
$destWidth = $maxWidth;
$destHeight = $srcHeight/$ratioWidth;
}
return array (ceil($destWidth), ceil($destHeight),
max($ratioWidth,$ratioHeight));
}
// http://doc.spip.org/@image_reduire
function image_reduire($img, $taille = -1, $taille_y = -1, $force=false, $cherche_image=false, $process='AUTO') {
// Determiner la taille x,y maxi
// prendre le reglage de previsu par defaut
if ($taille == -1)
$taille = isset($GLOBALS['meta']['taille_preview'])?$GLOBALS['meta']['taille_preview']:150;
if ($taille_y == -1)
$taille_y = $taille;
if ($taille == 0 AND $taille_y > 0)
$taille = 100000; # {0,300} -> c'est 300 qui compte
elseif ($taille > 0 AND $taille_y == 0)
$taille_y = 100000; # {300,0} -> c'est 300 qui compte
elseif ($taille == 0 AND $taille_y == 0)
return '';
$image = image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}",'png');
if (!$image){
spip_log("image_reduire_src:pas de version locale de $img");
// on peut resizer en mode html si on dispose des elements
if ($srcw = extraire_attribut($img, 'width')
AND $srch = extraire_attribut($img, 'height')) {
list($w,$h) = image_ratio($srcw, $srch, $taille, $taille_y);
return image_tag_changer_taille($img,$w,$h);
}
// la on n'a pas d'infos sur l'image source... on refile le truc a css
// sous la forme style='max-width: NNpx;'
return inserer_attribut($img, 'style',
"max-width: ${taille}px; max-height: ${taille_y}px");
}
// si l'image est plus petite que la cible retourner une copie cachee de l'image
if (($image['largeur']<=$taille)&&($image['hauteur']<=$taille_y)){
if ($image['creer']){
@copy($image['fichier'], $image['fichier_dest']);
}
return image_ecrire_tag($image,array('src'=>$image['fichier_dest']));
}
if ($image['creer']==false && !$force)
return image_ecrire_tag($image,array('src'=>$image['fichier_dest'],'width'=>$image['largeur_dest'],'height'=>$image['hauteur_dest']));
if ($cherche_image){
$cherche = cherche_image_nommee(substr($image['fichier'],0,-4), array($image["format_source"]));
if (!$cherche) return $img;
//list($chemin,$nom,$format) = $cherche;
}
if (in_array($image["format_source"],array('jpg','gif','png'))){
$destWidth = $image['largeur_dest'];
$destHeight = $image['hauteur_dest'];
$logo = $image['fichier'];
$date = $image["date_src"];
$preview = image_creer_vignette($image, $taille, $taille_y,$process,$force);
if ($preview) {
$logo = $preview['fichier'];
$destWidth = $preview['width'];
$destHeight = $preview['height'];
$date = $preview['date'];
}
// dans l'espace prive mettre un timestamp sur l'adresse
// de l'image, de facon a tromper le cache du navigateur
// quand on fait supprimer/reuploader un logo
// (pas de filemtime si SAFE MODE)
$date = _DIR_RESTREINT ? '' : ('?date='.$date);
return image_ecrire_tag($image,array('src'=>"$logo$date",'width'=>$destWidth,'height'=>$destHeight));
}
else
# SVG par exemple ? BMP, tiff ... les redacteurs osent tout!
return $img;
}
// Reduire une image d'un certain facteur
// http://doc.spip.org/@image_reduire_par
function image_reduire_par ($img, $val=1, $force=false) {
list ($hauteur,$largeur) = taille_image($img);
$l = round($largeur/$val);
$h = round($hauteur/$val);
if ($l > $h) $h = 0;
else $l = 0;
$img = image_reduire($img, $l, $h, $force);
return $img;
}
// Transforme l'image en PNG transparent
// alpha = 0: aucune transparence
// alpha = 127: completement transparent
// http://doc.spip.org/@image_alpha
function image_alpha($im, $alpha = 63)
{
$image = image_valeurs_trans($im, "alpha-$alpha", "png");
if (!$image) return("");
$x_i = $image["largeur"];
$y_i = $image["hauteur"];
$im = $image["fichier"];
$dest = $image["fichier_dest"];
$creer = $image["creer"];
if ($creer) {
// Creation de l'image en deux temps
// de facon a conserver les GIF transparents
$im = $image["fonction_imagecreatefrom"]($im);
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
$im2 = imagecreatetruecolor($x_i, $y_i);
@imagealphablending($im2, false);
@imagesavealpha($im2,true);
$color_t = ImageColorAllocateAlpha( $im2, 255, 255, 255 , 127 );
imagefill ($im2, 0, 0, $color_t);
imagecopy($im2, $im, 0, 0, 0, 0, $x_i, $y_i);
$im_ = imagecreatetruecolor($x_i, $y_i);
imagealphablending ($im_, FALSE );
imagesavealpha ( $im_, TRUE );
for ($x = 0; $x < $x_i; $x++) {
for ($y = 0; $y < $y_i; $y++) {
$rgb = ImageColorAt($im2, $x, $y);
if (function_exists(imagecolorallocatealpha)) {
$a = ($rgb >> 24) & 0xFF;
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$a_ = $alpha + $a - round($a*$alpha/127);
$rgb = imagecolorallocatealpha($im_, $r, $g, $b, $a_);
}
imagesetpixel ( $im_, $x, $y, $rgb );
}
}
$image["fonction_image"]($im_, "$dest");
imagedestroy($im_);
imagedestroy($im);
imagedestroy($im2);
}
$class = $image["class"];
if (strlen($class) > 1) $tags=" class='$class'";
$tags = "$tags alt='".$image["alt"]."'";
$style = $image["style"];
if (strlen($style) > 1) $tags="$tags style='$style'";
return "<img src='$dest'$tags />";
}
Christian Lefebvre
a validé
// http://doc.spip.org/@image_recadre
function image_recadre($im,$width,$height,$position='center', $background_color='white')
$image = image_valeurs_trans($im, "recadre-$width-$height-$position-$background_color");
if (!$image) return("");
$x_i = $image["largeur"];
$y_i = $image["hauteur"];
if ($width==0) $width=$x_i;
if ($height==0) $height=$y_i;
$offset_width = $x_i-$width;
$offset_height = $y_i-$height;
$position=strtolower($position);
if (strpos($position,'left')!==FALSE)
$offset_width=0;
elseif (strpos($position,'right')!==FALSE)
$offset_width=$offset_width;
else
$offset_width=intval(ceil($offset_width/2));
if (strpos($position,'top')!==FALSE)
$offset_height=0;
elseif (strpos($position,'bottom')!==FALSE)
$offset_height=$offset_height;
else
$offset_height=intval(ceil($offset_height/2));
$im = $image["fichier"];
$dest = $image["fichier_dest"];
$creer = $image["creer"];
if ($creer) {
$im = $image["fonction_imagecreatefrom"]($im);
$im_ = imagecreatetruecolor($width, $height);
@imagealphablending($im_, false);
@imagesavealpha($im_,true);
if ($background_color=='transparent')
$color_t = imagecolorallocatealpha( $im_, 255, 255, 255 , 127 );
else {
$bg = couleur_hex_to_dec($background_color);
$color_t = imagecolorallocate( $im_, $bg['red'], $bg['green'], $bg['blue']);
}
imagefill ($im_, 0, 0, $color_t);
imagecopy($im_, $im, max(0,-$offset_width), max(0,-$offset_height), max(0,$offset_width), max(0,$offset_height), min($width,$x_i), min($height,$y_i));
$image["fonction_image"]($im_, "$dest");
imagedestroy($im_);
imagedestroy($im);
}
return image_ecrire_tag($image,array('src'=>$dest,'width'=>$width,'height'=>$height));
// http://doc.spip.org/@image_flip_vertical
function image_flip_vertical($im)
{
$image = image_valeurs_trans($im, "flip_v");
if (!$image) return("");
$x_i = $image["largeur"];
$y_i = $image["hauteur"];
$im = $image["fichier"];
$dest = $image["fichier_dest"];
$creer = $image["creer"];
if ($creer) {
$im = $image["fonction_imagecreatefrom"]($im);
$im_ = imagecreatetruecolor($x_i, $y_i);
@imagealphablending($im_, false);
@imagesavealpha($im_,true);
$color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
imagefill ($im_, 0, 0, $color_t);
for ($x = 0; $x < $x_i; $x++) {
for ($y = 0; $y < $y_i; $y++) {
imagecopy($im_, $im, $x_i - $x - 1, $y, $x, $y, 1, 1);
}
}
$image["fonction_image"]($im_, "$dest");
imagedestroy($im_);
imagedestroy($im);
}
return image_ecrire_tag($image,array('src'=>$dest));
// http://doc.spip.org/@image_flip_horizontal
function image_flip_horizontal($im)
{
$image = image_valeurs_trans($im, "flip_h");
if (!$image) return("");
$x_i = $image["largeur"];
$y_i = $image["hauteur"];
$im = $image["fichier"];
$dest = $image["fichier_dest"];
$creer = $image["creer"];
if ($creer) {
$im = $image["fonction_imagecreatefrom"]($im);
$im_ = imagecreatetruecolor($x_i, $y_i);
@imagealphablending($im_, false);
@imagesavealpha($im_,true);
$color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
imagefill ($im_, 0, 0, $color_t);
for ($x = 0; $x < $x_i; $x++) {
for ($y = 0; $y < $y_i; $y++) {
imagecopy($im_, $im, $x, $y_i - $y - 1, $x, $y, 1, 1);
}
}
$image["fonction_image"]($im_, "$dest");
imagedestroy($im_);
imagedestroy($im);
}
return image_ecrire_tag($image,array('src'=>$dest));
// http://doc.spip.org/@image_masque
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
function image_masque($im, $masque, $pos="") {
// Passer, en plus de l'image d'origine,
// une image de "masque": un fichier PNG24 transparent.
// Le decoupage se fera selon la transparence du "masque",
// et les couleurs seront eclaircies/foncees selon de couleur du masque.
// Pour ne pas modifier la couleur, le masque doit etre en gris 50%.
//
// Si l'image source est plus grande que le masque, alors cette image est reduite a la taille du masque.
// Sinon, c'est la taille de l'image source qui est utilisee.
//
// $pos est une variable libre, qui permet de passer left=..., right=..., bottom=..., top=...
// dans ce cas, le pasque est place a ces positions sur l'image d'origine,
// et evidemment cette image d'origine n'est pas redimensionnee
//
// Positionnement horizontal: text-align=left, right, center
// Positionnement vertical : vertical-align: top, bottom, middle
// (les positionnements left, right, top, left sont relativement inutiles, mais coherence avec CSS)
//
// Choix du mode de fusion: mode=masque, normal, eclaircir, obscurcir, produit, difference
// masque: mode par defaut
// normal: place la nouvelle image par dessus l'ancienne
// eclaircir: place uniquement les points plus clairs
// obscurcir: place uniquement les points plus fonc'es
// produit: multiplie par le masque (points noirs rendent l'image noire, points blancs ne changent rien)
// difference: remplit avec l'ecart entre les couleurs d'origine et du masque
$mode = "masque";
$numargs = func_num_args();
$arg_list = func_get_args();
$texte = $arg_list[0];
for ($i = 1; $i < $numargs; $i++) {
if (ereg("\=", $arg_list[$i])) {
$nom_variable = substr($arg_list[$i], 0, strpos($arg_list[$i], "="));
$val_variable = substr($arg_list[$i], strpos($arg_list[$i], "=")+1, strlen($arg_list[$i]));
$variable["$nom_variable"] = $val_variable;
$defini["$nom_variable"] = 1;
}
}
if ($defini["mode"]) $mode = $variable["mode"];
$pos = md5(serialize($variable));
$image = image_valeurs_trans($im, "masque-$masque-$pos", "png");
if (!$image) return("");
$x_i = $image["largeur"];
$y_i = $image["hauteur"];
$im = $image["fichier"];
$dest = $image["fichier_dest"];
$creer = $image["creer"];
if ($defini["right"] OR $defini["left"] OR $defini["bottom"] OR $defini["top"] OR $defini["text-align"] OR $defini["vertical-align"]) {
$placer = true;
}
else $placer = false;
if ($creer) {
$masque = find_in_path($masque);
$mask = image_valeurs_trans($masque,"");
if (!is_array($mask)) return("");
$im_m = $mask["fichier"];
$x_m = $mask["largeur"];
$y_m = $mask["hauteur"];
$im2 = $mask["fonction_imagecreatefrom"]($masque);
cerdic
a validé
if ($mask["format_source"] == "gif" AND function_exists('ImageCopyResampled')) {
$im2_ = imagecreatetruecolor($x_m, $y_m);
// Si un GIF est transparent,
// fabriquer un PNG transparent
// Conserver la transparence
if (function_exists("imageAntiAlias")) imageAntiAlias($im2_,true);
@imagealphablending($im2_, false);
@imagesavealpha($im2_,true);
@ImageCopyResampled($im2_, $im2, 0, 0, 0, 0, $x_m, $y_m, $x_m, $y_m);
imagedestroy($im2);
$im2 = $im2_;
}
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
if ($placer) {
// On fabriquer une version "agrandie" du masque,
// aux dimensions de l'image source
// et on "installe" le masque dans cette image
// ainsi: aucun redimensionnement
$dx = 0;
$dy = 0;
if ($defini["right"]) {
$right = $variable["right"];
$dx = ($x_i - $x_m) - $right;
}
if ($defini["bottom"]) {
$bottom = $variable["bottom"];
$dy = ($y_i - $y_m) - $bottom;
}
if ($defini["top"]) {
$top = $variable["top"];
$dy = $top;
}
if ($defini["left"]) {
$left = $variable["left"];
$dx = $left;
}
if ($defini["text-align"]) {
$align = $variable["text-align"];
if ($align == "right") {
$right = 0;
$dx = ($x_i - $x_m);
} else if ($align == "left") {
$left = 0;
$dx = 0;
} else if ($align = "center") {
$dx = round( ($x_i - $x_m) / 2 ) ;
}
}
if ($defini["vertical-align"]) {
$valign = $variable["vertical-align"];
if ($valign == "bottom") {
$bottom = 0;
$dy = ($y_i - $y_m);
} else if ($valign == "top") {
$top = 0;
$dy = 0;
} else if ($valign = "middle") {
$dy = round( ($y_i - $y_m) / 2 ) ;
}
}
$im3 = imagecreatetruecolor($x_i, $y_i);
@imagealphablending($im3, false);
@imagesavealpha($im3,true);
if ($mode == "masque") $color_t = ImageColorAllocateAlpha( $im3, 128, 128, 128 , 0 );
else $color_t = ImageColorAllocateAlpha( $im3, 128, 128, 128 , 127 );
imagefill ($im3, 0, 0, $color_t);
imagecopy ( $im3, $im2, $dx, $dy, 0, 0, $x_m, $y_m);
imagedestroy($im2);
$im2 = imagecreatetruecolor($x_i, $y_i);
@imagealphablending($im2, false);
@imagesavealpha($im2,true);
imagecopy ( $im2, $im3, 0, 0, 0, 0, $x_i, $y_i);
imagedestroy($im3);
$x_m = $x_i;
$y_m = $y_i;
}
$rapport = $x_i / $x_m;
if (($y_i / $y_m) < $rapport ) {
$rapport = $y_i / $y_m;
}
$x_d = ceil($x_i / $rapport);
$y_d = ceil($y_i / $rapport);
if ($x_i < $x_m OR $y_i < $y_m) {
$x_dest = $x_i;
$y_dest = $y_i;
$x_dec = 0;
$y_dec = 0;
} else {
$x_dest = $x_m;
$y_dest = $y_m;
$x_dec = round(($x_d - $x_m) /2);
$y_dec = round(($y_d - $y_m) /2);
}
$nouveau = image_valeurs_trans(image_reduire($im, $x_d, $y_d),"");
if (!is_array($nouveau)) return("");
$im_n = $nouveau["fichier"];
$im = $nouveau["fonction_imagecreatefrom"]($im_n);
cerdic
a validé
if ($nouveau["format_source"] == "gif" AND function_exists('ImageCopyResampled')) {
$im_ = imagecreatetruecolor($x_dest, $y_dest);
// Si un GIF est transparent,
// fabriquer un PNG transparent
// Conserver la transparence
if (function_exists("imageAntiAlias")) imageAntiAlias($im_,true);
@imagealphablending($im_, false);
@imagesavealpha($im_,true);
@ImageCopyResampled($im_, $im, 0, 0, 0, 0, $x_dest, $y_dest, $x_dest, $y_dest);
imagedestroy($im);
$im = $im_;
}
$im_ = imagecreatetruecolor($x_dest, $y_dest);
@imagealphablending($im_, false);
@imagesavealpha($im_,true);
$color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
imagefill ($im_, 0, 0, $color_t);
for ($x = 0; $x < $x_dest; $x++) {
for ($y=0; $y < $y_dest; $y++) {
$rgb = ImageColorAt($im2, $x, $y);