source: spip-zone/_core_/plugins/filtres_images/filtres/images_transforme.php @ 41404

Last change on this file since 41404 was 41404, checked in by cedric@…, 11 years ago

utiliser _image_valeurs_trans dans image_masque pour accepter comme masque une balise <img> issue d'un filtre image et/ou une image avec un timestamp ?0123

File size: 45.4 KB
Line 
1<?php
2/***************************************************************************\
3 *  SPIP, Systeme de publication pour l'internet                           *
4 *                                                                         *
5 *  Copyright (c) 2001-2009                                                *
6 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
7 *                                                                         *
8 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
9 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
10\***************************************************************************/
11
12/**
13 * Toutes les fonctions image_xx de ce fichier :
14 *      - prennent une image en entree
15 *  - fournissent une image en sortie
16 *  - sont chainables les unes derrieres les autres dans toutes les combinaisons possibles
17 */
18
19// librairie de base du core
20include_spip('inc/filtres_images_mini');
21
22// 1/ Aplatir une image semi-transparente (supprimer couche alpha)
23// en remplissant la transparence avec couleur choisir $coul.
24// 2/ Forcer le format de sauvegarde (jpg, png, gif)
25// pour le format jpg, $qualite correspond au niveau de compression (defaut 85)
26// pour le format gif, $qualite correspond au nombre de couleurs dans la palette (defaut 128)
27// pour le format png, $qualite correspond au nombre de couleur dans la palette ou si 0 a une image truecolor (defaut truecolor)
28// attention, seul 128 est supporte en l'etat (production d'images avec palette reduite pas satisfaisante)
29// http://doc.spip.org/@image_aplatir
30// 3/ $transparence a "true" permet de conserver la transparence (utile pour conversion GIF)
31// http://doc.spip.org/@image_aplatir
32function image_aplatir($im, $format='jpg', $coul='000000', $qualite=NULL, $transparence=false)
33{
34        if ($qualite===NULL){
35                if ($format=='jpg') $qualite=_IMG_GD_QUALITE;
36                elseif ($format=='png') $qualite=0;
37                else $qualite=128;
38        }
39        $fonction = array('image_aplatir', func_get_args());
40        $image = _image_valeurs_trans($im, "aplatir-$format-$coul-$qualite-$transparence", $format, $fonction);
41
42        if (!$image) return("");
43
44        include_spip('inc/filtres');
45        $couleurs = _couleur_hex_to_dec($coul);
46        $dr= $couleurs["red"];
47        $dv= $couleurs["green"];
48        $db= $couleurs["blue"];
49
50        $x_i = $image["largeur"];
51        $y_i = $image["hauteur"];
52       
53        $im = $image["fichier"];
54        $dest = $image["fichier_dest"];
55       
56        $creer = $image["creer"];
57
58        if ($creer) {
59                $im = @$image["fonction_imagecreatefrom"]($im);
60                imagepalettetotruecolor($im);
61                $im_ = imagecreatetruecolor($x_i, $y_i);
62                if ($image["format_source"] == "gif" AND function_exists('ImageCopyResampled')) { 
63                        // Si un GIF est transparent,
64                        // fabriquer un PNG transparent 
65                        // Conserver la transparence
66                        @imagealphablending($im_, false); 
67                        @imagesavealpha($im_,true); 
68                        if (function_exists("imageAntiAlias")) imageAntiAlias($im_,true); 
69                        @ImageCopyResampled($im_, $im, 0, 0, 0, 0, $x_i, $y_i, $x_i, $y_i);
70                        imagedestroy($im);
71                        $im = $im_;
72                }
73               
74                // allouer la couleur de fond
75                if ($transparence) {
76                        @imagealphablending($im_, false); 
77                        @imagesavealpha($im_,true); 
78                        $color_t = imagecolorallocatealpha( $im_, $dr, $dv, $db, 127);
79                }
80                else $color_t = ImageColorAllocate( $im_, $dr, $dv, $db);
81               
82                imagefill ($im_, 0, 0, $color_t);
83
84                //??
85                //$dist = abs($trait);
86               
87                $transp_x = false;
88               
89                for ($x = 0; $x < $x_i; $x++) {
90                        for ($y=0; $y < $y_i; $y++) {
91                       
92                                $rgb = ImageColorAt($im, $x, $y);
93                                $a = ($rgb >> 24) & 0xFF;
94                                $r = ($rgb >> 16) & 0xFF;
95                                $g = ($rgb >> 8) & 0xFF;
96                                $b = $rgb & 0xFF;
97
98                                $a = (127-$a) / 127;
99                               
100                                if ($a == 1) { // Limiter calculs
101                                        $r = $r;
102                                        $g = $g;
103                                        $b = $b;
104                                }
105                                else if ($a == 0) { // Limiter calculs
106                                        $r = $dr;
107                                        $g = $dv;
108                                        $b = $db;
109                                       
110                                        $transp_x = $x; // Memoriser un point transparent
111                                        $transp_y = $y;
112                                       
113                                } else {
114                                        $r = round($a * $r + $dr * (1-$a));
115                                        $g = round($a * $g + $dv * (1-$a));
116                                        $b = round($a * $b + $db * (1-$a));
117                                }
118                                $a = (1-$a) *127;
119                                $color = ImageColorAllocateAlpha( $im_, $r, $g, $b, $a);
120                                imagesetpixel ($im_, $x, $y, $color);   
121                        }
122                }
123                // passer en palette si besoin
124                if ($format=='gif' OR ($format=='png' AND $qualite!==0)){
125                        // creer l'image finale a palette (on recycle l'image initiale)                 
126
127
128                        @imagetruecolortopalette($im,true,$qualite);
129
130
131                        //$im = imagecreate($x_i, $y_i);
132                        // copier l'image true color vers la palette
133                        imagecopy($im, $im_, 0, 0, 0, 0, $x_i, $y_i);
134                        // matcher les couleurs au mieux par rapport a l'image initiale
135                        // si la fonction est disponible (php>=4.3)
136                        if (function_exists('imagecolormatch'))
137                                @imagecolormatch($im_, $im);
138                               
139                        if ($format=='gif' && $transparence && $transp_x) {     
140                                $color_t = ImagecolorAt( $im, $transp_x, $transp_y);
141                                if ($format == "gif" && $transparence) @imagecolortransparent($im, $color_t);
142                        }
143                               
144                               
145                        // produire le resultat
146                        _image_gd_output($im, $image, $qualite);
147                }
148                else
149                        _image_gd_output($im_, $image, $qualite);
150                imagedestroy($im_);
151                imagedestroy($im);
152        }
153        return _image_ecrire_tag($image,array('src'=>$dest));
154}
155
156
157// Enregistrer une image dans un format donne
158// (conserve la transparence gif, png, ico)
159// utilise [->@image_aplatir]
160// http://doc.spip.org/@image_format
161function image_format($img, $format='png') {
162        $qualite = null;
163        if ($format=='png8') {$format='png';$qualite=128;}
164        return image_aplatir($img, $format, 'cccccc', $qualite, true);
165}
166
167
168// Transforme l'image en PNG transparent
169// alpha = 0: aucune transparence
170// alpha = 127: completement transparent
171// http://doc.spip.org/@image_alpha
172function image_alpha($im, $alpha = 63)
173{
174        $fonction = array('image_alpha', func_get_args());
175        $image = _image_valeurs_trans($im, "alpha-$alpha", "png",$fonction);
176        if (!$image) return("");
177       
178        $x_i = $image["largeur"];
179        $y_i = $image["hauteur"];
180       
181        $im = $image["fichier"];
182        $dest = $image["fichier_dest"];
183       
184        $creer = $image["creer"];
185       
186        if ($creer) {
187                // Creation de l'image en deux temps
188                // de facon a conserver les GIF transparents
189                $im = $image["fonction_imagecreatefrom"]($im);
190                imagepalettetotruecolor($im);
191                $im2 = imagecreatetruecolor($x_i, $y_i);
192                @imagealphablending($im2, false);
193                @imagesavealpha($im2,true);
194                $color_t = ImageColorAllocateAlpha( $im2, 255, 255, 255 , 127 );
195                imagefill ($im2, 0, 0, $color_t);
196                imagecopy($im2, $im, 0, 0, 0, 0, $x_i, $y_i);
197
198                $im_ = imagecreatetruecolor($x_i, $y_i);
199                imagealphablending ($im_, FALSE );
200                imagesavealpha ( $im_, TRUE );
201
202
203
204                for ($x = 0; $x < $x_i; $x++) {
205                        for ($y = 0; $y < $y_i; $y++) {
206                                $rgb = ImageColorAt($im2, $x, $y);
207                               
208                                if (function_exists('imagecolorallocatealpha')) {
209                                        $a = ($rgb >> 24) & 0xFF;
210                                        $r = ($rgb >> 16) & 0xFF;
211                                        $g = ($rgb >> 8) & 0xFF;
212                                        $b = $rgb & 0xFF;
213                                       
214                                       
215                                        $a_ = $alpha + $a - round($a*$alpha/127);
216                                        $rgb = imagecolorallocatealpha($im_, $r, $g, $b, $a_);
217                                }
218                                imagesetpixel ( $im_, $x, $y, $rgb );
219                        }
220                }
221                _image_gd_output($im_,$image);
222                imagedestroy($im_);
223                imagedestroy($im);
224                imagedestroy($im2);
225        }
226       
227
228        return _image_ecrire_tag($image,array('src'=>$dest));
229       
230}
231
232// http://doc.spip.org/@image_recadre
233function image_recadre($im,$width,$height,$position='center', $background_color='white')
234{
235        $fonction = array('image_recadre', func_get_args());
236        $image = _image_valeurs_trans($im, "recadre-$width-$height-$position-$background_color",false,$fonction);
237       
238        if (!$image) return("");
239       
240        $x_i = $image["largeur"];
241        $y_i = $image["hauteur"];
242       
243        if ($width==0) $width=$x_i;
244        if ($height==0) $height=$y_i;
245       
246        $offset_width = $x_i-$width;
247        $offset_height = $y_i-$height;
248        $position=strtolower($position);
249        if (strpos($position,'left')!==FALSE){
250                if (preg_match(';left=(\d{1}\d+);', $position, $left)){
251                        $offset_width=$left[1]; 
252                }
253                else{
254                        $offset_width=0;
255                }
256        }
257        elseif (strpos($position,'right')!==FALSE)
258                $offset_width=$offset_width;
259        else
260                $offset_width=intval(ceil($offset_width/2));
261
262        if (strpos($position,'top')!==FALSE){
263                if (preg_match(';top=(\d{1}\d+);', $position, $top)){
264                        $offset_height=$top[1];
265                }
266                else{
267                        $offset_height=0;
268                }
269        }
270        elseif (strpos($position,'bottom')!==FALSE)
271                $offset_height=$offset_height;
272        else
273                $offset_height=intval(ceil($offset_height/2));
274       
275        $im = $image["fichier"];
276        $dest = $image["fichier_dest"];
277       
278        $creer = $image["creer"];
279       
280        if ($creer) {
281                $im = $image["fonction_imagecreatefrom"]($im);
282                imagepalettetotruecolor($im);
283                $im_ = imagecreatetruecolor($width, $height);
284                @imagealphablending($im_, false);
285                @imagesavealpha($im_,true);
286
287                if ($background_color=='transparent')
288                        $color_t = imagecolorallocatealpha( $im_, 255, 255, 255 , 127 );
289                else {
290                        $bg = _couleur_hex_to_dec($background_color);
291                        $color_t = imagecolorallocate( $im_, $bg['red'], $bg['green'], $bg['blue']);
292                }
293                imagefill ($im_, 0, 0, $color_t);
294                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));
295
296                _image_gd_output($im_,$image);
297                imagedestroy($im_);
298                imagedestroy($im);
299        }
300       
301        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>$width,'height'=>$height));
302}
303
304
305/**
306 * Recadrer une image dans le rectangle le plus petit possible sans perte
307 * de pixels non transparent
308 *
309 * @param string $im
310 * @return string
311 */
312function image_recadre_mini($im)
313{
314        $fonction = array('image_recadre_mini', func_get_args());
315        $image = _image_valeurs_trans($im, "recadre_mini",false,$fonction);
316
317        if (!$image) return("");
318
319        $width = $image["largeur"];
320        $height = $image["hauteur"];
321
322        $im = $image["fichier"];
323        $dest = $image["fichier_dest"];
324
325        $creer = $image["creer"];
326        if ($creer) {
327                $im = $image["fonction_imagecreatefrom"]($im);
328                imagepalettetotruecolor($im);
329
330                // trouver le rectangle mini qui contient des infos de couleur
331                // recherche optimisee qui ne balaye que par zone
332                $min_x = $width;
333                $min_y = $height;
334                $max_y = $max_x = 0;
335                $yy = 0;
336                while ($yy<=$height/2 AND $max_y<=$min_y){
337                        if($yy<$min_y)
338                                for ($xx = 0; $xx < $width; $xx++) {
339                                        $color_index = imagecolorat($im, $xx, $yy);
340                                        $color_tran = imagecolorsforindex($im, $color_index);
341                                        if ($color_tran['alpha']!==127){
342                                                $min_y = min($yy,$min_y);
343                                                $max_y = max($height-1-$yy,$max_y);
344                                                break;
345                                        }
346                                }
347                        if($height-1-$yy>$max_y)
348                                for ($xx = 0; $xx < $width; $xx++) {
349                                        $color_index = imagecolorat($im, $xx, $height-1-$yy);
350                                        $color_tran = imagecolorsforindex($im, $color_index);
351                                        if ($color_tran['alpha']!==127){
352                                                $min_y = min($yy,$min_y);
353                                                $max_y = max($height-1-$yy,$max_y);
354                                                break;
355                                        }
356                                }
357                        $yy++;
358                }
359                $min_y = min($max_y,$min_y); // tout a 0 aucun pixel trouve
360
361                $xx = 0;
362                while ($xx<=$width/2 AND $max_x<=$min_x){
363                        if ($xx<$min_x)
364                                for ($yy = $min_y; $yy < $max_y; $yy++) {
365                                        $color_index = imagecolorat($im, $xx, $yy);
366                                        $color_tran = imagecolorsforindex($im, $color_index);
367                                        if ($color_tran['alpha']!==127){
368                                                $min_x = min($xx,$min_x);
369                                                $max_x = max($xx,$max_x);
370                                                break; // inutile de continuer sur cette colonne
371                                        }
372                                }
373                        if ($width-1-$xx>$max_x)
374                                for ($yy = $min_y; $yy < $max_y; $yy++) {
375                                        $color_index = imagecolorat($im, $width-1-$xx, $yy);
376                                        $color_tran = imagecolorsforindex($im, $color_index);
377                                        if ($color_tran['alpha']!==127){
378                                                $min_x = min($width-1-$xx,$min_x);
379                                                $max_x = max($width-1-$xx,$max_x);
380                                                break; // inutile de continuer sur cette colonne
381                                        }
382                                }
383                        $xx++;
384                }
385                $min_x = min($max_x,$min_x); // tout a 0 aucun pixel trouve
386
387                $width = $max_x-$min_x+1;
388                $height = $max_y-$min_y+1;
389
390                $im_ = imagecreatetruecolor($width, $height);
391                @imagealphablending($im_, false);
392                @imagesavealpha($im_,true);
393
394                $color_t = imagecolorallocatealpha( $im_, 255, 255, 255 , 127 );
395                imagefill ($im_, 0, 0, $color_t);
396                imagecopy($im_, $im, 0, 0, $min_x, $min_y, $width, $height);
397
398                _image_gd_output($im_,$image);
399                imagedestroy($im_);
400                imagedestroy($im);
401        }
402        else {
403                list ($height,$width) = taille_image($image['fichier_dest']);
404        }
405
406        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>$width,'height'=>$height));
407}
408
409
410// http://doc.spip.org/@image_flip_vertical
411function image_flip_vertical($im)
412{
413        $fonction = array('image_flip_vertical', func_get_args());
414        $image = _image_valeurs_trans($im, "flip_v", false,$fonction);
415        if (!$image) return("");
416       
417        $x_i = $image["largeur"];
418        $y_i = $image["hauteur"];
419       
420        $im = $image["fichier"];
421        $dest = $image["fichier_dest"];
422       
423        $creer = $image["creer"];
424       
425        if ($creer) {
426                $im = $image["fonction_imagecreatefrom"]($im);
427                imagepalettetotruecolor($im);
428                $im_ = imagecreatetruecolor($x_i, $y_i);
429                @imagealphablending($im_, false);
430                @imagesavealpha($im_,true);
431       
432                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
433                imagefill ($im_, 0, 0, $color_t);
434
435                for ($x = 0; $x < $x_i; $x++) {
436                        for ($y = 0; $y < $y_i; $y++) {
437                                imagecopy($im_, $im, $x_i - $x - 1, $y, $x, $y, 1, 1);
438                        }
439                }
440
441                _image_gd_output($im_,$image);
442                imagedestroy($im_);
443                imagedestroy($im);
444        }
445       
446        return _image_ecrire_tag($image,array('src'=>$dest));
447}
448
449// http://doc.spip.org/@image_flip_horizontal
450function image_flip_horizontal($im)
451{
452        $fonction = array('image_flip_horizontal', func_get_args());
453        $image = _image_valeurs_trans($im, "flip_h",false,$fonction);
454        if (!$image) return("");
455       
456        $x_i = $image["largeur"];
457        $y_i = $image["hauteur"];
458       
459        $im = $image["fichier"];
460        $dest = $image["fichier_dest"];
461       
462        $creer = $image["creer"];
463       
464        if ($creer) {
465                $im = $image["fonction_imagecreatefrom"]($im);
466                imagepalettetotruecolor($im);
467                $im_ = imagecreatetruecolor($x_i, $y_i);
468                @imagealphablending($im_, false);
469                @imagesavealpha($im_,true);
470       
471                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
472                imagefill ($im_, 0, 0, $color_t);
473
474                for ($x = 0; $x < $x_i; $x++) {
475                        for ($y = 0; $y < $y_i; $y++) {
476                                imagecopy($im_, $im, $x, $y_i - $y - 1, $x, $y, 1, 1);
477                        }
478                }
479                _image_gd_output($im_,$image);
480                imagedestroy($im_);
481                imagedestroy($im);
482        }
483       
484        return _image_ecrire_tag($image,array('src'=>$dest));
485}
486
487// http://doc.spip.org/@image_masque
488function image_masque($im, $masque, $pos="") {
489        // Passer, en plus de l'image d'origine,
490        // une image de "masque": un fichier PNG24 transparent.
491        // Le decoupage se fera selon la transparence du "masque",
492        // et les couleurs seront eclaircies/foncees selon de couleur du masque.
493        // Pour ne pas modifier la couleur, le masque doit etre en gris 50%.
494        //
495        // Si l'image source est plus grande que le masque, alors cette image est reduite a la taille du masque.
496        // Sinon, c'est la taille de l'image source qui est utilisee.
497        //
498        // $pos est une variable libre, qui permet de passer left=..., right=..., bottom=..., top=...
499        // dans ce cas, le pasque est place a ces positions sur l'image d'origine,
500        // et evidemment cette image d'origine n'est pas redimensionnee
501        //
502        // Positionnement horizontal: text-align=left, right, center
503        // Positionnement vertical : vertical-align: top, bottom, middle
504        // (les positionnements left, right, top, left sont relativement inutiles, mais coherence avec CSS)
505        //
506        // Choix du mode de fusion: mode=masque, normal, eclaircir, obscurcir, produit, difference
507        // masque: mode par defaut
508        // normal: place la nouvelle image par dessus l'ancienne
509        // eclaircir: place uniquement les points plus clairs
510        // obscurcir: place uniquement les points plus fonc'es
511        // produit: multiplie par le masque (points noirs rendent l'image noire, points blancs ne changent rien)
512        // difference: remplit avec l'ecart entre les couleurs d'origine et du masque
513
514        $mode = "masque";
515
516
517        $numargs = func_num_args();
518        $arg_list = func_get_args();
519        $texte = $arg_list[0];
520        for ($i = 1; $i < $numargs; $i++) {
521                if ( ($p = strpos($arg_list[$i],"=")) !==false) {
522                        $nom_variable = substr($arg_list[$i], 0, $p);
523                        $val_variable = substr($arg_list[$i], $p+1);
524                        $variable["$nom_variable"] = $val_variable;
525                        $defini["$nom_variable"] = 1;
526                }
527        }
528        if ($defini["mode"]) $mode = $variable["mode"];
529
530        // utiliser _image_valeurs_trans pour accepter comme masque :
531        // - une balise <img src='...' />
532        // - une image avec un timestamp ?01234
533        $mask = _image_valeurs_trans($masque, "source-image_masque", "png",null, true);
534        if (!$mask) return("");
535        $masque = $mask['fichier'];
536
537        $pos = md5(serialize($variable).$mask['date_src']);
538        $fonction = array('image_masque', func_get_args());
539        $image = _image_valeurs_trans($im, "masque-$masque-$pos", "png",$fonction);
540        if (!$image) return("");
541
542        $x_i = $image["largeur"];
543        $y_i = $image["hauteur"];
544       
545        $im = $image["fichier"];
546        $dest = $image["fichier_dest"];
547       
548        $creer = $image["creer"];
549
550
551        if ($defini["right"] OR $defini["left"] OR $defini["bottom"] OR $defini["top"] OR $defini["text-align"] OR $defini["vertical-align"]) {
552                $placer = true;
553        }
554        else $placer = false;
555
556        if ($creer) {
557               
558                $im_m = $mask["fichier"];
559                $x_m = $mask["largeur"];
560                $y_m = $mask["hauteur"];
561       
562                $im2 = $mask["fonction_imagecreatefrom"]($masque);
563                if ($mask["format_source"] == "gif" AND function_exists('ImageCopyResampled')) { 
564                        $im2_ = imagecreatetruecolor($x_m, $y_m);
565                        // Si un GIF est transparent,
566                        // fabriquer un PNG transparent 
567                        // Conserver la transparence
568                        if (function_exists("imageAntiAlias")) imageAntiAlias($im2_,true); 
569                        @imagealphablending($im2_, false); 
570                        @imagesavealpha($im2_,true); 
571                        @ImageCopyResampled($im2_, $im2, 0, 0, 0, 0, $x_m, $y_m, $x_m, $y_m);
572                        imagedestroy($im2);
573                        $im2 = $im2_;
574                }
575               
576                if ($placer) {
577                        // On fabriquer une version "agrandie" du masque,
578                        // aux dimensions de l'image source
579                        // et on "installe" le masque dans cette image
580                        // ainsi: aucun redimensionnement
581                       
582                        $dx = 0;
583                        $dy = 0;
584                       
585                        if ($defini["right"]) {
586                                $right = $variable["right"];
587                                $dx = ($x_i - $x_m) - $right;
588                        }
589                        if ($defini["bottom"]) {
590                                $bottom = $variable["bottom"];
591                                $dy = ($y_i - $y_m) - $bottom;
592                                }
593                        if ($defini["top"]) {
594                                $top = $variable["top"];
595                                $dy = $top;
596                        }
597                        if ($defini["left"]) {
598                                $left = $variable["left"];
599                                $dx = $left;
600                        }
601                        if ($defini["text-align"]) {
602                                $align = $variable["text-align"];
603                                if ($align == "right") {
604                                        $right = 0;
605                                        $dx = ($x_i - $x_m);
606                                } else if ($align == "left") {
607                                        $left = 0;
608                                        $dx = 0;
609                                } else if ($align = "center") {
610                                        $dx = round( ($x_i - $x_m) / 2 ) ;
611                                }
612                        }
613                        if ($defini["vertical-align"]) {
614                                $valign = $variable["vertical-align"];
615                                if ($valign == "bottom") {
616                                        $bottom = 0;
617                                        $dy = ($y_i - $y_m);
618                                } else if ($valign == "top") {
619                                        $top = 0;
620                                        $dy = 0;
621                                } else if ($valign = "middle") {
622                                        $dy = round( ($y_i - $y_m) / 2 ) ;
623                                }
624                        }
625                       
626                       
627                        $im3 = imagecreatetruecolor($x_i, $y_i);
628                        @imagealphablending($im3, false);
629                        @imagesavealpha($im3,true);
630                        if ($mode == "masque") $color_t = ImageColorAllocateAlpha( $im3, 128, 128, 128 , 0 );
631                        else $color_t = ImageColorAllocateAlpha( $im3, 128, 128, 128 , 127 );
632                        imagefill ($im3, 0, 0, $color_t);
633
634                       
635
636                        imagecopy ( $im3, $im2, $dx, $dy, 0, 0, $x_m, $y_m);   
637
638                        imagedestroy($im2);
639                        $im2 = imagecreatetruecolor($x_i, $y_i);
640                        @imagealphablending($im2, false);
641                        @imagesavealpha($im2,true);
642                       
643                       
644                       
645                        imagecopy ( $im2, $im3, 0, 0, 0, 0, $x_i, $y_i);                       
646                        imagedestroy($im3);
647                        $x_m = $x_i;
648                        $y_m = $y_i;
649                }
650               
651       
652                $rapport = $x_i / $x_m;
653                if (($y_i / $y_m) < $rapport ) {
654                        $rapport = $y_i / $y_m;
655                }
656                       
657                $x_d = ceil($x_i / $rapport);
658                $y_d = ceil($y_i / $rapport);
659               
660
661                if ($x_i < $x_m OR $y_i < $y_m) {
662                        $x_dest = $x_i;
663                        $y_dest = $y_i;
664                        $x_dec = 0;
665                        $y_dec = 0;
666                } else {
667                        $x_dest = $x_m;
668                        $y_dest = $y_m;
669                        $x_dec = round(($x_d - $x_m) /2);
670                        $y_dec = round(($y_d - $y_m) /2);
671                }
672
673
674                $nouveau = _image_valeurs_trans(image_reduire($im, $x_d, $y_d),"");
675                if (!is_array($nouveau)) return("");
676                $im_n = $nouveau["fichier"];
677               
678       
679                $im = $nouveau["fonction_imagecreatefrom"]($im_n);
680                imagepalettetotruecolor($im);
681                if ($nouveau["format_source"] == "gif" AND function_exists('ImageCopyResampled')) { 
682                        $im_ = imagecreatetruecolor($x_dest, $y_dest);
683                        // Si un GIF est transparent,
684                        // fabriquer un PNG transparent 
685                        // Conserver la transparence
686                        if (function_exists("imageAntiAlias")) imageAntiAlias($im_,true); 
687                        @imagealphablending($im_, false); 
688                        @imagesavealpha($im_,true); 
689                        @ImageCopyResampled($im_, $im, 0, 0, 0, 0, $x_dest, $y_dest, $x_dest, $y_dest);
690                        imagedestroy($im);
691                        $im = $im_;
692                }
693                $im_ = imagecreatetruecolor($x_dest, $y_dest);
694                @imagealphablending($im_, false);
695                @imagesavealpha($im_,true);
696                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
697                imagefill ($im_, 0, 0, $color_t);
698
699
700                for ($x = 0; $x < $x_dest; $x++) {
701                        for ($y=0; $y < $y_dest; $y++) {
702                                $rgb = ImageColorAt($im2, $x, $y);
703                                $a = ($rgb >> 24) & 0xFF;
704                                $r = ($rgb >> 16) & 0xFF;
705                                $g = ($rgb >> 8) & 0xFF;
706                                $b = $rgb & 0xFF;
707                               
708
709                                $rgb2 = ImageColorAt($im, $x+$x_dec, $y+$y_dec);
710                                $a2 = ($rgb2 >> 24) & 0xFF;
711                                $r2 = ($rgb2 >> 16) & 0xFF;
712                                $g2 = ($rgb2 >> 8) & 0xFF;
713                                $b2 = $rgb2 & 0xFF;
714                               
715                               
716                               
717                                if ($mode == "normal") {
718                                        $v = (127 - $a) / 127;
719                                        if ($v == 1) {
720                                                $r_ = $r;
721                                                $g_ = $g;
722                                                $b_ = $b;
723                                        } else {
724                                                $v2 = (127 - $a2) / 127;
725                                                if ($v+$v2 == 0) {
726                                                        $r_ = $r2;
727                                                        $g_ = $g2;
728                                                        $b_ = $b2;
729                                                } else if ($v2 ==0) {
730                                                        $r_ = $r;
731                                                        $g_ = $g;
732                                                        $b_ = $b;
733                                                } else if ($v == 0) {
734                                                        $r_ = $r2;
735                                                        $g_ = $g2;
736                                                        $b_ = $b2;
737                                                }else {
738                                                        $r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
739                                                        $g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
740                                                        $b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
741                                                }
742                                        }
743                                        $a_ = min($a,$a2);
744                                } elseif ($mode == "produit" OR $mode == "difference") {                                       
745
746                                        if ($mode == "produit") {
747                                                $r = ($r/255) * $r2;
748                                                $g = ($g/255) * $g2;
749                                                $b = ($b/255) * $b2;
750                                        } else if ($mode == "difference") {
751                                                $r = abs($r-$r2);
752                                                $g = abs($g-$g2);
753                                                $b = abs($b-$b2);                               
754                                        }
755
756                                        $r = max(0, min($r, 255));
757                                        $g = max(0, min($g, 255));
758                                        $b = max(0, min($b, 255));
759
760                                        $v = (127 - $a) / 127;
761                                        if ($v == 1) {
762                                                $r_ = $r;
763                                                $g_ = $g;
764                                                $b_ = $b;
765                                        } else {
766                                                $v2 = (127 - $a2) / 127;
767                                                if ($v+$v2 == 0) {
768                                                        $r_ = $r2;
769                                                        $g_ = $g2;
770                                                        $b_ = $b2;
771                                                } else {
772                                                        $r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
773                                                        $g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
774                                                        $b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
775                                                }
776                                        }
777
778
779                                        $a_ = $a2;
780                                } elseif ($mode == "eclaircir" OR $mode == "obscurcir") {
781                                        $v = (127 - $a) / 127;
782                                        if ($v == 1) {
783                                                $r_ = $r;
784                                                $g_ = $g;
785                                                $b_ = $b;
786                                        } else {
787                                                $v2 = (127 - $a2) / 127;
788                                                if ($v+$v2 == 0) {
789                                                        $r_ = $r2;
790                                                        $g_ = $g2;
791                                                        $b_ = $b2;
792                                                } else {
793                                                        $r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
794                                                        $g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
795                                                        $b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
796                                                }
797                                        }
798                                        if ($mode == "eclaircir") {
799                                                $r_ = max ($r_, $r2);
800                                                $g_ = max ($g_, $g2);
801                                                $b_ = max ($b_, $b2);
802                                        } else {
803                                                $r_ = min ($r_, $r2);
804                                                $g_ = min ($g_, $g2);
805                                                $b_ = min ($b_, $b2);                                   
806                                        }
807                                       
808                                        $a_ = min($a,$a2);
809                                } else {
810                                        $r_ = $r2 + 1 * ($r - 127);
811                                        $r_ = max(0, min($r_, 255));
812                                        $g_ = $g2 + 1 * ($g - 127);
813                                        $g_ = max(0, min($g_, 255));
814                                        $b_ = $b2 + 1 * ($b - 127);
815                                        $b_ = max(0, min($b_, 255));
816                                       
817                                        $a_ = $a + $a2 - round($a*$a2/127);
818                                }
819
820                                $color = ImageColorAllocateAlpha( $im_, $r_, $g_, $b_ , $a_ );
821                                imagesetpixel ($im_, $x, $y, $color);                   
822                        }
823                }
824
825                _image_gd_output($im_,$image);
826                imagedestroy($im_);
827                imagedestroy($im);
828                imagedestroy($im2);
829
830        }
831        $x_dest = largeur($dest);
832        $y_dest = hauteur($dest);
833        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>$x_dest,'height'=>$y_dest));
834}
835
836// Passage de l'image en noir et blanc
837// un noir & blanc "photo" n'est pas "neutre": les composantes de couleur sont
838// ponderees pour obtenir le niveau de gris;
839// on peut ici regler cette ponderation en "pour mille"
840// http://doc.spip.org/@image_nb
841function image_nb($im, $val_r = 299, $val_g = 587, $val_b = 114)
842{
843        $fonction = array('image_nb', func_get_args());
844        $image = _image_valeurs_trans($im, "nb-$val_r-$val_g-$val_b",false,$fonction);
845        if (!$image) return("");
846       
847        $x_i = $image["largeur"];
848        $y_i = $image["hauteur"];
849       
850        $im = $image["fichier"];
851        $dest = $image["fichier_dest"];
852       
853        $creer = $image["creer"];
854       
855        // Methode precise
856        // resultat plus beau, mais tres lourd
857        // Et: indispensable pour preserver transparence!
858
859        if ($creer) {
860                // Creation de l'image en deux temps
861                // de facon a conserver les GIF transparents
862                $im = $image["fonction_imagecreatefrom"]($im);
863                imagepalettetotruecolor($im);
864                $im_ = imagecreatetruecolor($x_i, $y_i);
865                @imagealphablending($im_, false);
866                @imagesavealpha($im_,true);
867                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
868                imagefill ($im_, 0, 0, $color_t);
869                imagecopy($im_, $im, 0, 0, 0, 0, $x_i, $y_i);
870               
871                for ($x = 0; $x < $x_i; $x++) {
872                        for ($y=0; $y < $y_i; $y++) {
873                                $rgb = ImageColorAt($im_, $x, $y);
874                                $a = ($rgb >> 24) & 0xFF;
875                                $r = ($rgb >> 16) & 0xFF;
876                                $g = ($rgb >> 8) & 0xFF;
877                                $b = $rgb & 0xFF;
878
879                                $c = round(($val_r * $r / 1000) + ($val_g * $g / 1000) + ($val_b * $b / 1000));
880                                if ($c < 0) $c = 0;
881                                if ($c > 254) $c = 254;
882                               
883                               
884                                $color = ImageColorAllocateAlpha( $im_, $c, $c, $c , $a );
885                                imagesetpixel ($im_, $x, $y, $color);                   
886                        }
887                }
888                _image_gd_output($im_,$image);
889                imagedestroy($im_);
890                imagedestroy($im);
891        }
892
893        return _image_ecrire_tag($image,array('src'=>$dest));
894}
895
896// http://doc.spip.org/@image_flou
897function image_flou($im,$niveau=3)
898{
899        // Il s'agit d'une modification du script blur qu'on trouve un peu partout:
900        // + la transparence est geree correctement
901        // + les dimensions de l'image sont augmentees pour flouter les bords
902        $coeffs = array (
903                                array ( 1),
904                                array ( 1, 1), 
905                                array ( 1, 2, 1),
906                                array ( 1, 3, 3, 1),
907                                array ( 1, 4, 6, 4, 1),
908                                array ( 1, 5, 10, 10, 5, 1),
909                                array ( 1, 6, 15, 20, 15, 6, 1),
910                                array ( 1, 7, 21, 35, 35, 21, 7, 1),
911                                array ( 1, 8, 28, 56, 70, 56, 28, 8, 1),
912                                array ( 1, 9, 36, 84, 126, 126, 84, 36, 9, 1),
913                                array ( 1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1),
914                                array ( 1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1)
915                                );
916       
917        $fonction = array('image_flou', func_get_args());
918        $image = _image_valeurs_trans($im, "flou-$niveau", false,$fonction);
919        if (!$image) return("");
920       
921        $x_i = $image["largeur"];
922        $y_i = $image["hauteur"];
923        $sum = pow (2, $niveau);
924
925        $im = $image["fichier"];
926        $dest = $image["fichier_dest"];
927       
928        $creer = $image["creer"];
929       
930        // Methode precise
931        // resultat plus beau, mais tres lourd
932        // Et: indispensable pour preserver transparence!
933
934        if ($creer) {
935                // Creation de l'image en deux temps
936                // de facon a conserver les GIF transparents
937                $im = $image["fonction_imagecreatefrom"]($im);
938                imagepalettetotruecolor($im);
939                $temp1 = imagecreatetruecolor($x_i+$niveau, $y_i);
940                $temp2 = imagecreatetruecolor($x_i+$niveau, $y_i+$niveau);
941               
942                @imagealphablending($temp1, false);
943                @imagesavealpha($temp1,true);
944                @imagealphablending($temp2, false);
945                @imagesavealpha($temp2,true);
946
947               
948                for ($i = 0; $i < $x_i+$niveau; $i++) {
949                        for ($j=0; $j < $y_i; $j++) {
950                                $suma=0;
951                                $sumr=0;
952                                $sumg=0;
953                                $sumb=0;
954                                $sum = 0;
955                                $sum_ = 0;
956                                for ( $k=0 ; $k <= $niveau ; ++$k ) {
957                                        $color = imagecolorat($im, $i_ = ($i-$niveau)+$k , $j);
958
959                                        $a = ($color >> 24) & 0xFF;
960                                        $r = ($color >> 16) & 0xFF;
961                                        $g = ($color >> 8) & 0xFF;
962                                        $b = ($color) & 0xFF;
963                                       
964                                        if ($i_ < 0 OR $i_ >= $x_i) $a = 127;
965                                       
966                                        $coef = $coeffs[$niveau][$k];
967                                        $suma += $a*$coef;
968                                        $ac = ((127-$a) / 127);
969                                       
970                                        $ac = $ac*$ac;
971                                       
972                                        $sumr += $r * $coef * $ac;
973                                        $sumg += $g * $coef * $ac;
974                                        $sumb += $b * $coef * $ac;
975                                        $sum += $coef * $ac;
976                                        $sum_ += $coef;
977                                }
978                                if ($sum > 0) $color = ImageColorAllocateAlpha ($temp1, $sumr/$sum, $sumg/$sum, $sumb/$sum, $suma/$sum_);
979                                else $color = ImageColorAllocateAlpha ($temp1, 255, 255, 255, 127);
980                                imagesetpixel($temp1,$i,$j,$color);
981                        }
982                }
983                imagedestroy($im);
984                for ($i = 0; $i < $x_i+$niveau; $i++) {
985                        for ($j=0; $j < $y_i+$niveau; $j++) {
986                                $suma=0;
987                                $sumr=0;
988                                $sumg=0;
989                                $sumb=0;
990                                $sum = 0;
991                                $sum_ = 0;
992                                for ( $k=0 ; $k <= $niveau ; ++$k ) {
993                                        $color = imagecolorat($temp1, $i, $j_ = $j-$niveau+$k);
994                                        $a = ($color >> 24) & 0xFF;
995                                        $r = ($color >> 16) & 0xFF;
996                                        $g = ($color >> 8) & 0xFF;
997                                        $b = ($color) & 0xFF;
998                                        if ($j_ < 0 OR $j_ >= $y_i) $a = 127;
999                                       
1000                                        $suma += $a*$coeffs[$niveau][$k];
1001                                        $ac = ((127-$a) / 127);
1002                                                                               
1003                                        $sumr += $r * $coeffs[$niveau][$k] * $ac;
1004                                        $sumg += $g * $coeffs[$niveau][$k] * $ac;
1005                                        $sumb += $b * $coeffs[$niveau][$k] * $ac;
1006                                        $sum += $coeffs[$niveau][$k] * $ac;
1007                                        $sum_ += $coeffs[$niveau][$k];
1008                                       
1009                                }
1010                                if ($sum > 0) $color = ImageColorAllocateAlpha ($temp2, $sumr/$sum, $sumg/$sum, $sumb/$sum, $suma/$sum_);
1011                                else $color = ImageColorAllocateAlpha ($temp2, 255, 255, 255, 127);
1012                                imagesetpixel($temp2,$i,$j,$color);
1013                        }
1014                }
1015       
1016                _image_gd_output($temp2,$image);
1017                imagedestroy($temp1);   
1018                imagedestroy($temp2);   
1019        }
1020       
1021        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>($x_i+$niveau),'height'=>($y_i+$niveau)));
1022}
1023
1024// http://doc.spip.org/@image_RotateBicubic
1025function image_RotateBicubic($src_img, $angle, $bicubic=0) {
1026        include_spip('filtres/images_lib');
1027   
1028        if (round($angle/90)*90 == $angle) {
1029                $droit = true;
1030                if (round($angle/180)*180 == $angle) $rot = 180;
1031                else $rot = 90;
1032        }
1033        else 
1034                $droit = false;
1035   
1036        // convert degrees to radians
1037        $angle = $angle + 180;
1038        $angle = deg2rad($angle);
1039       
1040       
1041       
1042        $src_x = imagesx($src_img);
1043        $src_y = imagesy($src_img);
1044       
1045       
1046        $center_x = floor(($src_x-1)/2);
1047        $center_y = floor(($src_y-1)/2);
1048       
1049        $cosangle = cos($angle);
1050        $sinangle = sin($angle);
1051
1052        // calculer dimensions en simplifiant angles droits, ce qui evite "floutage"
1053        // des rotations a angle droit
1054        if (!$droit) {
1055                $corners=array(array(0,0), array($src_x,0), array($src_x,$src_y), array(0,$src_y));
1056       
1057                foreach($corners as $key=>$value) {
1058                        $value[0]-=$center_x;        //Translate coords to center for rotation
1059                        $value[1]-=$center_y;
1060                        $temp=array();
1061                        $temp[0]=$value[0]*$cosangle+$value[1]*$sinangle;
1062                        $temp[1]=$value[1]*$cosangle-$value[0]*$sinangle;
1063                        $corners[$key]=$temp;   
1064                }
1065           
1066                $min_x=1000000000000000;
1067                $max_x=-1000000000000000;
1068                $min_y=1000000000000000;
1069                $max_y=-1000000000000000;
1070           
1071                foreach($corners as $key => $value) {
1072                        if($value[0]<$min_x)
1073                                $min_x=$value[0];
1074                        if($value[0]>$max_x)
1075                                $max_x=$value[0];
1076                       
1077                        if($value[1]<$min_y)
1078                                $min_y=$value[1];
1079                        if($value[1]>$max_y)
1080                                $max_y=$value[1];
1081          }
1082       
1083                $rotate_width=ceil($max_x-$min_x);
1084                $rotate_height=ceil($max_y-$min_y);
1085        }
1086        else {
1087                if ($rot == 180) {
1088                        $rotate_height = $src_y;
1089                        $rotate_width = $src_x;
1090                } else {
1091                        $rotate_height = $src_x;
1092                        $rotate_width = $src_y;
1093                }
1094                $bicubic = false;
1095        }
1096       
1097       
1098        $rotate=imagecreatetruecolor($rotate_width,$rotate_height);
1099        imagealphablending($rotate, false);
1100        imagesavealpha($rotate, true);
1101       
1102        $cosangle = cos($angle);
1103        $sinangle = sin($angle);
1104   
1105        // arrondir pour rotations angle droit (car cos et sin dans {-1,0,1})
1106        if ($droit) {
1107                $cosangle = round($cosangle);
1108                $sinangle = round($sinangle);
1109        }
1110
1111        $newcenter_x = ($rotate_width-1)/2;
1112        $newcenter_y = ($rotate_height-1)/2;
1113
1114   
1115        for ($y = 0; $y < $rotate_height; $y++) {
1116                for ($x = 0; $x < $rotate_width; $x++) {
1117                        // rotate...
1118                        $old_x = ((($newcenter_x-$x) * $cosangle + ($newcenter_y-$y) * $sinangle))
1119                         + $center_x;
1120                        $old_y = ((($newcenter_y-$y) * $cosangle - ($newcenter_x-$x) * $sinangle))
1121                         + $center_y; 
1122         
1123                        $old_x = ceil($old_x);
1124                        $old_y = ceil($old_y);
1125         
1126                        if ( $old_x >= 0 && $old_x < $src_x
1127                         && $old_y >= 0 && $old_y < $src_y ) {
1128                                if ($bicubic == true) {
1129                                        $xo = $old_x;
1130                                        $x0 = floor($xo);
1131                                        $x1 = ceil($xo);
1132                                        $yo = $old_y;
1133                                        $y0 = floor($yo);
1134                                        $y1 = ceil($yo);
1135       
1136                                        // on prend chaque point, mais on pondere en fonction de la distance
1137                                        $rgb = ImageColorAt($src_img, $x0, $y0); 
1138                                        $a1 = ($rgb >> 24) & 0xFF;
1139                                        $r1 = ($rgb >> 16) & 0xFF;
1140                                        $g1 = ($rgb >> 8) & 0xFF;
1141                                        $b1 = $rgb & 0xFF;
1142                                        $d1 = _image_distance_pixel($xo, $yo, $x0, $y0);
1143                                       
1144                                        $rgb = ImageColorAt($src_img, $x1, $y0); 
1145                                        $a2 = ($rgb >> 24) & 0xFF;
1146                                        $r2 = ($rgb >> 16) & 0xFF;
1147                                        $g2 = ($rgb >> 8) & 0xFF;
1148                                        $b2 = $rgb & 0xFF;
1149                                        $d2 = _image_distance_pixel($xo, $yo, $x1, $y0);
1150                                       
1151                                        $rgb = ImageColorAt($src_img,$x0, $y1); 
1152                                        $a3 = ($rgb >> 24) & 0xFF;
1153                                        $r3 = ($rgb >> 16) & 0xFF;
1154                                        $g3 = ($rgb >> 8) & 0xFF;
1155                                        $b3 = $rgb & 0xFF;
1156                                        $d3 = _image_distance_pixel($xo, $yo, $x0, $y1);
1157                                       
1158                                        $rgb = ImageColorAt($src_img,$x1, $y1);
1159                                        $a4 = ($rgb >> 24) & 0xFF;
1160                                        $r4 = ($rgb >> 16) & 0xFF;
1161                                        $g4 = ($rgb >> 8) & 0xFF;
1162                                        $b4 = $rgb & 0xFF;
1163                                        $d4 = _image_distance_pixel($xo, $yo, $x1, $y1);
1164                                       
1165                                        $ac1 = ((127-$a1) / 127);
1166                                        $ac2 = ((127-$a2) / 127);
1167                                        $ac3 = ((127-$a3) / 127);
1168                                        $ac4 = ((127-$a4) / 127);
1169
1170                                        // limiter impact des couleurs transparentes,
1171                                        // mais attention tout transp: division par 0
1172                                        if ($ac1*$d1 + $ac2*$d2 + $ac3+$d3 + $ac4+$d4 > 0) {
1173                                                if ($ac1 > 0) $d1 = $d1 * $ac1;
1174                                                if ($ac2 > 0) $d2 = $d2 * $ac2;
1175                                                if ($ac3 > 0) $d3 = $d3 * $ac3;
1176                                                if ($ac4 > 0) $d4 = $d4 * $ac4;
1177                                        }
1178                                       
1179                                        $tot  = $d1 + $d2 + $d3 + $d4;
1180
1181                                        $r = round((($d1*$r1)+($d2*$r2)+($d3*$r3)+($d4*$r4))/$tot);
1182                                        $g = round((($d1*$g1+($d2*$g2)+$d3*$g3+$d4*$g4))/$tot);
1183                                        $b = round((($d1*$b1+($d2*$b2)+$d3*$b3+$d4*$b4))/$tot);
1184                                        $a = round((($d1*$a1+($d2*$a2)+$d3*$a3+$d4*$a4))/$tot);
1185                                        $color = imagecolorallocatealpha($src_img, $r,$g,$b,$a);
1186                                } 
1187                                else {
1188                                        $color = imagecolorat($src_img, round($old_x), round($old_y));
1189                                }
1190                        }
1191                        else {
1192                                // this line sets the background colour
1193                                $color = imagecolorallocatealpha($src_img, 255, 255, 255, 127);
1194                        }
1195                        @imagesetpixel($rotate, $x, $y, $color);
1196                }
1197        }
1198        return $rotate;
1199}
1200
1201// permet de faire tourner une image d'un angle quelconque
1202// la fonction "crop" n'est pas implementee...
1203// http://doc.spip.org/@image_rotation
1204function image_rotation($im, $angle, $crop=false)
1205{
1206        $fonction = array('image_rotation', func_get_args());
1207        $image = _image_valeurs_trans($im, "rot-$angle-$crop", "png", $fonction);
1208        if (!$image) return("");
1209       
1210        $im = $image["fichier"];
1211        $dest = $image["fichier_dest"];
1212       
1213        $creer = $image["creer"];
1214       
1215        if ($creer) {
1216                $effectuer_gd = true;
1217
1218                if (function_exists('imagick_rotate')) {
1219                        $mask = imagick_getcanvas( "#ff0000", $x, $y );
1220                        $handle = imagick_readimage ($im);
1221                        if ($handle && imagick_isopaqueimage( $handle )) {
1222                                imagick_rotate( $handle, $angle);
1223                                imagick_writeimage( $handle, $dest);
1224                                $effectuer_gd = false;
1225                        }
1226                }
1227                elseif(is_callable(array('Imagick','rotateImage'))){
1228                        $imagick = new Imagick();
1229                        $imagick->readImage($im);
1230                        $imagick->rotateImage(new ImagickPixel('#ffffff'), $angle);
1231                        $imagick->writeImage($dest);
1232                        $effectuer_gd = false;
1233                }
1234                else if ($GLOBALS['meta']['image_process'] == "convert") {
1235                        if (_CONVERT_COMMAND!='') {
1236                                @define ('_CONVERT_COMMAND', 'convert');
1237                                @define ('_ROTATE_COMMAND', _CONVERT_COMMAND.' -rotate %t %src %dest');
1238                        } else
1239                                @define ('_ROTATE_COMMAND', '');
1240                        if (_ROTATE_COMMAND!=='') {
1241                                $commande = str_replace(
1242                                        array('%t', '%src', '%dest'),
1243                                        array(
1244                                                $angle,
1245                                                escapeshellcmd($im),
1246                                                escapeshellcmd($dest)
1247                                        ),
1248                                        _ROTATE_COMMAND);
1249                                spip_log($commande);
1250                                exec($commande);
1251                                if (file_exists($dest)) // precaution
1252                                        $effectuer_gd = false;
1253                        }
1254                }
1255                if ($effectuer_gd) {
1256                        // Creation de l'image en deux temps
1257                        // de facon a conserver les GIF transparents
1258                        $im = $image["fonction_imagecreatefrom"]($im);
1259                        imagepalettetotruecolor($im);
1260                        $im = image_RotateBicubic($im, $angle, true);
1261                        _image_gd_output($im,$image);
1262                        imagedestroy($im);
1263                }
1264        }
1265        list ($src_y,$src_x) = taille_image($dest);
1266        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>$src_x,'height'=>$src_y));
1267}
1268
1269// Permet d'appliquer un filtre php_imagick a une image
1270// par exemple: [(#LOGO_ARTICLE|image_imagick{imagick_wave,20,60})]
1271// liste des fonctions: http://www.linux-nantes.org/~fmonnier/doc/imagick/
1272// http://doc.spip.org/@image_imagick
1273function image_imagick () {
1274        $tous = func_get_args();
1275        $img = $tous[0];
1276        $fonc = $tous[1];
1277        $tous[0]="";
1278        $tous_var = join($tous, "-");
1279
1280        $fonction = array('image_imagick', func_get_args());
1281        $image = _image_valeurs_trans($img, "$tous_var", "png",$fonction);
1282        if (!$image) return("");
1283       
1284        $im = $image["fichier"];
1285        $dest = $image["fichier_dest"];
1286       
1287        $creer = $image["creer"];
1288       
1289        if ($creer) {
1290                if (function_exists($fonc)) {
1291
1292                        $handle = imagick_readimage ($im);
1293                        $arr[0] = $handle;
1294                        for ($i=2; $i < count($tous); $i++) $arr[] = $tous[$i];
1295                        call_user_func_array($fonc, $arr);
1296                        // Creer image dans fichier temporaire, puis renommer vers "bon" fichier
1297                        // de facon a eviter time_out pendant creation de l'image definitive
1298                        $tmp = preg_replace(",[.]png$,i", "-tmp.png", $dest);
1299                        imagick_writeimage( $handle, $tmp);
1300                        rename($tmp, $dest);
1301                        ecrire_fichier($dest.".src",serialize($image));
1302                } 
1303        }
1304        list ($src_y,$src_x) = taille_image($dest);
1305        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>$src_x,'height'=>$src_y));
1306
1307}
1308
1309// Permet de rendre une image
1310// plus claire (gamma > 0)
1311// ou plus foncee (gamma < 0)
1312// http://doc.spip.org/@image_gamma
1313function image_gamma($im, $gamma = 0){
1314        include_spip('filtres/images_lib');
1315        $fonction = array('image_gamma', func_get_args());
1316        $image = _image_valeurs_trans($im, "gamma-$gamma",false,$fonction);
1317        if (!$image) return("");
1318       
1319        $x_i = $image["largeur"];
1320        $y_i = $image["hauteur"];
1321       
1322        $im = $image["fichier"];
1323        $dest = $image["fichier_dest"];
1324       
1325        $creer = $image["creer"];
1326       
1327        if ($creer) {
1328                // Creation de l'image en deux temps
1329                // de facon a conserver les GIF transparents
1330                $im = $image["fonction_imagecreatefrom"]($im);
1331                imagepalettetotruecolor($im);
1332                $im_ = imagecreatetruecolor($x_i, $y_i);
1333                @imagealphablending($im_, false);
1334                @imagesavealpha($im_,true);
1335                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
1336                imagefill ($im_, 0, 0, $color_t);
1337                imagecopy($im_, $im, 0, 0, 0, 0, $x_i, $y_i);
1338       
1339                for ($x = 0; $x < $x_i; $x++) {
1340                        for ($y=0; $y < $y_i; $y++) {
1341                                $rgb = ImageColorAt($im_, $x, $y);
1342                                $a = ($rgb >> 24) & 0xFF;
1343                                $r = ($rgb >> 16) & 0xFF;
1344                                $g = ($rgb >> 8) & 0xFF;
1345                                $b = $rgb & 0xFF;
1346
1347                                $r = _image_decale_composante($r, $gamma);
1348                                $g = _image_decale_composante($g, $gamma);
1349                                $b = _image_decale_composante($b, $gamma);
1350
1351                                $color = ImageColorAllocateAlpha( $im_, $r, $g, $b , $a );
1352                                imagesetpixel ($im_, $x, $y, $color);                   
1353                        }
1354                }
1355                _image_gd_output($im_,$image);
1356        }
1357        return _image_ecrire_tag($image,array('src'=>$dest));
1358}
1359
1360// Passe l'image en "sepia"
1361// On peut fixer les valeurs RGB
1362// de la couleur "complementaire" pour forcer une dominante
1363//function image_sepia($im, $dr = 137, $dv = 111, $db = 94)
1364// http://doc.spip.org/@image_sepia
1365function image_sepia($im, $rgb = "896f5e"){
1366        include_spip('filtres/images_lib');
1367       
1368        if (!function_exists("imagecreatetruecolor")) return $im;
1369       
1370        $couleurs = _couleur_hex_to_dec($rgb);
1371        $dr= $couleurs["red"];
1372        $dv= $couleurs["green"];
1373        $db= $couleurs["blue"];
1374               
1375        $fonction = array('image_sepia', func_get_args());
1376        $image = _image_valeurs_trans($im, "sepia-$dr-$dv-$db",false,$fonction);
1377        if (!$image) return("");
1378       
1379        $x_i = $image["largeur"];
1380        $y_i = $image["hauteur"];
1381       
1382        $im = $image["fichier"];
1383        $dest = $image["fichier_dest"];
1384       
1385        $creer = $image["creer"];
1386       
1387        if ($creer) {
1388                // Creation de l'image en deux temps
1389                // de facon a conserver les GIF transparents
1390                $im = $image["fonction_imagecreatefrom"]($im);
1391                imagepalettetotruecolor($im);
1392                $im_ = imagecreatetruecolor($x_i, $y_i);
1393                @imagealphablending($im_, false);
1394                @imagesavealpha($im_,true);
1395                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
1396                imagefill ($im_, 0, 0, $color_t);
1397                imagecopy($im_, $im, 0, 0, 0, 0, $x_i, $y_i);
1398       
1399                for ($x = 0; $x < $x_i; $x++) {
1400                        for ($y=0; $y < $y_i; $y++) {
1401                                $rgb = ImageColorAt($im_, $x, $y);
1402                                $a = ($rgb >> 24) & 0xFF;
1403                                $r = ($rgb >> 16) & 0xFF;
1404                                $g = ($rgb >> 8) & 0xFF;
1405                                $b = $rgb & 0xFF;
1406
1407                                $r = round(.299 * $r + .587 * $g + .114 * $b);
1408                                $g = $r;
1409                                $b = $r;
1410
1411
1412                                $r = _image_decale_composante_127($r, $dr);
1413                                $g = _image_decale_composante_127($g, $dv);
1414                                $b = _image_decale_composante_127($b, $db);
1415
1416                                $color = ImageColorAllocateAlpha( $im_, $r, $g, $b , $a );
1417                                imagesetpixel ($im_, $x, $y, $color);                   
1418                        }
1419                }
1420                _image_gd_output($im_,$image);
1421                imagedestroy($im_);
1422                imagedestroy($im);
1423        }
1424       
1425        return _image_ecrire_tag($image,array('src'=>$dest));
1426}
1427
1428
1429// Renforcer la nettete d'une image
1430// http://doc.spip.org/@image_renforcement
1431function image_renforcement($im, $k=0.5)
1432{
1433        $fonction = array('image_flou', func_get_args());
1434        $image = _image_valeurs_trans($im, "renforcement-$k",false,$fonction);
1435        if (!$image) return("");
1436       
1437        $x_i = $image["largeur"];
1438        $y_i = $image["hauteur"];
1439        $im = $image["fichier"];
1440        $dest = $image["fichier_dest"];
1441        $creer = $image["creer"];
1442       
1443        if ($creer) {
1444                $im = $image["fonction_imagecreatefrom"]($im);
1445                imagepalettetotruecolor($im);
1446                $im_ = imagecreatetruecolor($x_i, $y_i);
1447                @imagealphablending($im_, false);
1448                @imagesavealpha($im_,true);
1449                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
1450                imagefill ($im_, 0, 0, $color_t);
1451
1452                for ($x = 0; $x < $x_i; $x++) {
1453                        for ($y=0; $y < $y_i; $y++) {           
1454
1455                $rgb[1][0]=imagecolorat($im,$x,$y-1);
1456                $rgb[0][1]=imagecolorat($im,$x-1,$y);
1457                $rgb[1][1]=imagecolorat($im,$x,$y);
1458                $rgb[2][1]=imagecolorat($im,$x+1,$y);
1459                $rgb[1][2]=imagecolorat($im,$x,$y+1);
1460               
1461               
1462                if ($x-1 < 0) $rgb[0][1] = $rgb[1][1];
1463                if ($y-1 < 0) $rgb[1][0] = $rgb[1][1];
1464                if ($x+1 == $x_i) $rgb[2][1] = $rgb[1][1];
1465                if ($y+1 == $y_i) $rgb[1][2] = $rgb[1][1];
1466
1467                $a = ($rgb[0][0] >> 24) & 0xFF;
1468                $r = -$k *(($rgb[1][0] >> 16) & 0xFF) +
1469                         -$k *(($rgb[0][1] >> 16) & 0xFF) +
1470                        (1+4*$k) *(($rgb[1][1] >> 16) & 0xFF) +
1471                         -$k *(($rgb[2][1] >> 16) & 0xFF) +
1472                         -$k *(($rgb[1][2] >> 16) & 0xFF) ;
1473
1474                $g = -$k *(($rgb[1][0] >> 8) & 0xFF) +
1475                         -$k *(($rgb[0][1] >> 8) & 0xFF) +
1476                         (1+4*$k) *(($rgb[1][1] >> 8) & 0xFF) +
1477                         -$k *(($rgb[2][1] >> 8) & 0xFF) +
1478                         -$k *(($rgb[1][2] >> 8) & 0xFF) ;
1479
1480                $b = -$k *($rgb[1][0] & 0xFF) +
1481                         -$k *($rgb[0][1] & 0xFF) +
1482                        (1+4*$k) *($rgb[1][1] & 0xFF) +
1483                         -$k *($rgb[2][1] & 0xFF) +
1484                         -$k *($rgb[1][2] & 0xFF) ;
1485
1486                $r=min(255,max(0,$r));
1487                $g=min(255,max(0,$g));
1488                $b=min(255,max(0,$b));
1489
1490
1491                $color = ImageColorAllocateAlpha( $im_, $r, $g, $b , $a );
1492                imagesetpixel ($im_, $x, $y, $color);                   
1493                        }
1494                }               
1495                _image_gd_output($im_,$image);
1496        }
1497
1498        return _image_ecrire_tag($image,array('src'=>$dest));
1499}
1500
1501
1502
1503
1504//
1505// alpha = 0: aucune transparence
1506// alpha = 127: completement transparent
1507/**
1508 * Transforme la couleur de fond de l'image en transparence
1509 * Le filtre ne g�re pas la notion de contiguite aux bords, et affectera tous les pixels de l'image dans la couleur visee
1510 * $background_color : couleur cible
1511 * $tolerance : distance L1 dans l'espace RGB des couleur autour de la couleur $background_color pour lequel la transparence sera appliquee
1512 * $alpha : transparence a appliquer pour les pixels de la couleur cibles avec la tolerance ci-dessus
1513 * $coeff_lissage : coeff applique a la tolerance pour determiner la decroissance de la transparence fonction de la distance L1 entre la couleur du pixel et la couleur cible
1514 *
1515 * @param string $im
1516 * @param string $background_color
1517 * @param int $tolerance
1518 * @param int $alpha
1519 * @param float $coeff_lissage
1520 * @return string
1521 */
1522function image_fond_transparent($im, $background_color, $tolerance=12, $alpha = 127, $coeff_lissage=7)
1523{
1524        $fonction = array('image_fond_transparent', func_get_args());
1525        $image = _image_valeurs_trans($im, "fond_transparent-$background_color-$tolerance-$coeff_lissage-$alpha", "png", $fonction);
1526        if (!$image) return("");
1527       
1528        $x_i = $image["largeur"];
1529        $y_i = $image["hauteur"];
1530       
1531        $im = $image["fichier"];
1532        $dest = $image["fichier_dest"];
1533       
1534        $creer = $image["creer"];
1535       
1536        if (true OR $creer) {
1537                $bg = _couleur_hex_to_dec($background_color);
1538                $bg_r = $bg['red'];
1539                $bg_g = $bg['green'];
1540                $bg_b = $bg['blue'];
1541       
1542                // Creation de l'image en deux temps
1543                // de facon a conserver les GIF transparents
1544                $im = $image["fonction_imagecreatefrom"]($im);
1545                imagepalettetotruecolor($im);
1546                $im2 = imagecreatetruecolor($x_i, $y_i);
1547                @imagealphablending($im2, false);
1548                @imagesavealpha($im2,true);
1549                $color_t = ImageColorAllocateAlpha( $im2, 255, 255, 255 , 127 );
1550                imagefill ($im2, 0, 0, $color_t);
1551                imagecopy($im2, $im, 0, 0, 0, 0, $x_i, $y_i);
1552
1553                $im_ = imagecreatetruecolor($x_i, $y_i);
1554                imagealphablending ($im_, FALSE );
1555                imagesavealpha ( $im_, TRUE );
1556                $color_f = ImageColorAllocateAlpha( $im_, 255, 255, 255 , $alpha );
1557
1558                for ($x = 0; $x < $x_i; $x++) {
1559                        for ($y = 0; $y < $y_i; $y++) {
1560                                $rgb = ImageColorAt($im2, $x, $y);
1561                                $r = ($rgb >> 16) & 0xFF;
1562                                $g = ($rgb >> 8) & 0xFF;
1563                                $b = $rgb & 0xFF;
1564                                if ((($d=abs($r-$bg_r)+abs($g-$bg_g)+abs($b-$bg_b))<=$tolerance)){
1565                                        imagesetpixel ( $im_, $x, $y, $color_f );
1566                                }
1567                                elseif ($tolerance AND $d<=($coeff_lissage+1)*$tolerance){
1568                                        $transp = round($alpha*(1-($d-$tolerance)/($coeff_lissage*$tolerance)));
1569                                        $color_p = ImageColorAllocateAlpha( $im_, $r, $g, $b , $transp);                                       
1570                                        imagesetpixel ( $im_, $x, $y, $color_p );
1571                                }
1572                                else
1573                                        imagesetpixel ( $im_, $x, $y, $rgb );
1574                        }
1575                }
1576                _image_gd_output($im_,$image);
1577                imagedestroy($im_);
1578                imagedestroy($im);
1579                imagedestroy($im2);
1580        }
1581       
1582        return _image_ecrire_tag($image,array('src'=>$dest));
1583}
1584?>
Note: See TracBrowser for help on using the repository browser.