source: spip-zone/_core_/branches/spip-2.1/plugins/filtres_images/filtres/images_transforme.php @ 48203

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

les differentes méthodes du filtre |image_rotation n'étaient pas équivalentes du point de vue des coins issus de la rotation :
image_RotateBicubic produit des coins transparents, il faut donc que les méthodes alternatives le fassent aussi.
La version moderne de Imagick() et convert en ligne de commande sont ici traitées. Il reste un doute sur l'ancienne version de imagick, qu'on repouse en 3ème choix du coup.

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        $masque = find_in_path($masque);
531        $pos = md5(serialize($variable).@filemtime($masque));
532
533        $fonction = array('image_masque', func_get_args());
534        $image = _image_valeurs_trans($im, "masque-$masque-$pos", "png",$fonction);
535        if (!$image) return("");
536
537        $x_i = $image["largeur"];
538        $y_i = $image["hauteur"];
539       
540        $im = $image["fichier"];
541        $dest = $image["fichier_dest"];
542       
543        $creer = $image["creer"];
544
545
546        if ($defini["right"] OR $defini["left"] OR $defini["bottom"] OR $defini["top"] OR $defini["text-align"] OR $defini["vertical-align"]) {
547                $placer = true;
548        }
549        else $placer = false;
550
551        if ($creer) {
552               
553                $mask = _image_valeurs_trans($masque,"");
554                if (!is_array($mask)) return("");
555                $im_m = $mask["fichier"];
556                $x_m = $mask["largeur"];
557                $y_m = $mask["hauteur"];
558       
559                $im2 = $mask["fonction_imagecreatefrom"]($masque);
560                if ($mask["format_source"] == "gif" AND function_exists('ImageCopyResampled')) { 
561                        $im2_ = imagecreatetruecolor($x_m, $y_m);
562                        // Si un GIF est transparent,
563                        // fabriquer un PNG transparent 
564                        // Conserver la transparence
565                        if (function_exists("imageAntiAlias")) imageAntiAlias($im2_,true); 
566                        @imagealphablending($im2_, false); 
567                        @imagesavealpha($im2_,true); 
568                        @ImageCopyResampled($im2_, $im2, 0, 0, 0, 0, $x_m, $y_m, $x_m, $y_m);
569                        imagedestroy($im2);
570                        $im2 = $im2_;
571                }
572               
573                if ($placer) {
574                        // On fabriquer une version "agrandie" du masque,
575                        // aux dimensions de l'image source
576                        // et on "installe" le masque dans cette image
577                        // ainsi: aucun redimensionnement
578                       
579                        $dx = 0;
580                        $dy = 0;
581                       
582                        if ($defini["right"]) {
583                                $right = $variable["right"];
584                                $dx = ($x_i - $x_m) - $right;
585                        }
586                        if ($defini["bottom"]) {
587                                $bottom = $variable["bottom"];
588                                $dy = ($y_i - $y_m) - $bottom;
589                                }
590                        if ($defini["top"]) {
591                                $top = $variable["top"];
592                                $dy = $top;
593                        }
594                        if ($defini["left"]) {
595                                $left = $variable["left"];
596                                $dx = $left;
597                        }
598                        if ($defini["text-align"]) {
599                                $align = $variable["text-align"];
600                                if ($align == "right") {
601                                        $right = 0;
602                                        $dx = ($x_i - $x_m);
603                                } else if ($align == "left") {
604                                        $left = 0;
605                                        $dx = 0;
606                                } else if ($align = "center") {
607                                        $dx = round( ($x_i - $x_m) / 2 ) ;
608                                }
609                        }
610                        if ($defini["vertical-align"]) {
611                                $valign = $variable["vertical-align"];
612                                if ($valign == "bottom") {
613                                        $bottom = 0;
614                                        $dy = ($y_i - $y_m);
615                                } else if ($valign == "top") {
616                                        $top = 0;
617                                        $dy = 0;
618                                } else if ($valign = "middle") {
619                                        $dy = round( ($y_i - $y_m) / 2 ) ;
620                                }
621                        }
622                       
623                       
624                        $im3 = imagecreatetruecolor($x_i, $y_i);
625                        @imagealphablending($im3, false);
626                        @imagesavealpha($im3,true);
627                        if ($mode == "masque") $color_t = ImageColorAllocateAlpha( $im3, 128, 128, 128 , 0 );
628                        else $color_t = ImageColorAllocateAlpha( $im3, 128, 128, 128 , 127 );
629                        imagefill ($im3, 0, 0, $color_t);
630
631                       
632
633                        imagecopy ( $im3, $im2, $dx, $dy, 0, 0, $x_m, $y_m);   
634
635                        imagedestroy($im2);
636                        $im2 = imagecreatetruecolor($x_i, $y_i);
637                        @imagealphablending($im2, false);
638                        @imagesavealpha($im2,true);
639                       
640                       
641                       
642                        imagecopy ( $im2, $im3, 0, 0, 0, 0, $x_i, $y_i);                       
643                        imagedestroy($im3);
644                        $x_m = $x_i;
645                        $y_m = $y_i;
646                }
647               
648       
649                $rapport = $x_i / $x_m;
650                if (($y_i / $y_m) < $rapport ) {
651                        $rapport = $y_i / $y_m;
652                }
653                       
654                $x_d = ceil($x_i / $rapport);
655                $y_d = ceil($y_i / $rapport);
656               
657
658                if ($x_i < $x_m OR $y_i < $y_m) {
659                        $x_dest = $x_i;
660                        $y_dest = $y_i;
661                        $x_dec = 0;
662                        $y_dec = 0;
663                } else {
664                        $x_dest = $x_m;
665                        $y_dest = $y_m;
666                        $x_dec = round(($x_d - $x_m) /2);
667                        $y_dec = round(($y_d - $y_m) /2);
668                }
669
670
671                $nouveau = _image_valeurs_trans(image_reduire($im, $x_d, $y_d),"");
672                if (!is_array($nouveau)) return("");
673                $im_n = $nouveau["fichier"];
674               
675       
676                $im = $nouveau["fonction_imagecreatefrom"]($im_n);
677                imagepalettetotruecolor($im);
678                if ($nouveau["format_source"] == "gif" AND function_exists('ImageCopyResampled')) { 
679                        $im_ = imagecreatetruecolor($x_dest, $y_dest);
680                        // Si un GIF est transparent,
681                        // fabriquer un PNG transparent 
682                        // Conserver la transparence
683                        if (function_exists("imageAntiAlias")) imageAntiAlias($im_,true); 
684                        @imagealphablending($im_, false); 
685                        @imagesavealpha($im_,true); 
686                        @ImageCopyResampled($im_, $im, 0, 0, 0, 0, $x_dest, $y_dest, $x_dest, $y_dest);
687                        imagedestroy($im);
688                        $im = $im_;
689                }
690                $im_ = imagecreatetruecolor($x_dest, $y_dest);
691                @imagealphablending($im_, false);
692                @imagesavealpha($im_,true);
693                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
694                imagefill ($im_, 0, 0, $color_t);
695
696
697                for ($x = 0; $x < $x_dest; $x++) {
698                        for ($y=0; $y < $y_dest; $y++) {
699                                $rgb = ImageColorAt($im2, $x, $y);
700                                $a = ($rgb >> 24) & 0xFF;
701                                $r = ($rgb >> 16) & 0xFF;
702                                $g = ($rgb >> 8) & 0xFF;
703                                $b = $rgb & 0xFF;
704                               
705
706                                $rgb2 = ImageColorAt($im, $x+$x_dec, $y+$y_dec);
707                                $a2 = ($rgb2 >> 24) & 0xFF;
708                                $r2 = ($rgb2 >> 16) & 0xFF;
709                                $g2 = ($rgb2 >> 8) & 0xFF;
710                                $b2 = $rgb2 & 0xFF;
711                               
712                               
713                               
714                                if ($mode == "normal") {
715                                        $v = (127 - $a) / 127;
716                                        if ($v == 1) {
717                                                $r_ = $r;
718                                                $g_ = $g;
719                                                $b_ = $b;
720                                        } else {
721                                                $v2 = (127 - $a2) / 127;
722                                                if ($v+$v2 == 0) {
723                                                        $r_ = $r2;
724                                                        $g_ = $g2;
725                                                        $b_ = $b2;
726                                                } else if ($v2 ==0) {
727                                                        $r_ = $r;
728                                                        $g_ = $g;
729                                                        $b_ = $b;
730                                                } else if ($v == 0) {
731                                                        $r_ = $r2;
732                                                        $g_ = $g2;
733                                                        $b_ = $b2;
734                                                }else {
735                                                        $r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
736                                                        $g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
737                                                        $b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
738                                                }
739                                        }
740                                        $a_ = min($a,$a2);
741                                } elseif ($mode == "produit" OR $mode == "difference") {                                       
742
743                                        if ($mode == "produit") {
744                                                $r = ($r/255) * $r2;
745                                                $g = ($g/255) * $g2;
746                                                $b = ($b/255) * $b2;
747                                        } else if ($mode == "difference") {
748                                                $r = abs($r-$r2);
749                                                $g = abs($g-$g2);
750                                                $b = abs($b-$b2);                               
751                                        }
752
753                                        $r = max(0, min($r, 255));
754                                        $g = max(0, min($g, 255));
755                                        $b = max(0, min($b, 255));
756
757                                        $v = (127 - $a) / 127;
758                                        if ($v == 1) {
759                                                $r_ = $r;
760                                                $g_ = $g;
761                                                $b_ = $b;
762                                        } else {
763                                                $v2 = (127 - $a2) / 127;
764                                                if ($v+$v2 == 0) {
765                                                        $r_ = $r2;
766                                                        $g_ = $g2;
767                                                        $b_ = $b2;
768                                                } else {
769                                                        $r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
770                                                        $g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
771                                                        $b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
772                                                }
773                                        }
774
775
776                                        $a_ = $a2;
777                                } elseif ($mode == "eclaircir" OR $mode == "obscurcir") {
778                                        $v = (127 - $a) / 127;
779                                        if ($v == 1) {
780                                                $r_ = $r;
781                                                $g_ = $g;
782                                                $b_ = $b;
783                                        } else {
784                                                $v2 = (127 - $a2) / 127;
785                                                if ($v+$v2 == 0) {
786                                                        $r_ = $r2;
787                                                        $g_ = $g2;
788                                                        $b_ = $b2;
789                                                } else {
790                                                        $r_ = $r + (($r2 - $r) * $v2 * (1 - $v));
791                                                        $g_ = $g + (($g2 - $g) * $v2 * (1 - $v));
792                                                        $b_ = $b + (($b2 - $b) * $v2 * (1 - $v));
793                                                }
794                                        }
795                                        if ($mode == "eclaircir") {
796                                                $r_ = max ($r_, $r2);
797                                                $g_ = max ($g_, $g2);
798                                                $b_ = max ($b_, $b2);
799                                        } else {
800                                                $r_ = min ($r_, $r2);
801                                                $g_ = min ($g_, $g2);
802                                                $b_ = min ($b_, $b2);                                   
803                                        }
804                                       
805                                        $a_ = min($a,$a2);
806                                } else {
807                                        $r_ = $r2 + 1 * ($r - 127);
808                                        $r_ = max(0, min($r_, 255));
809                                        $g_ = $g2 + 1 * ($g - 127);
810                                        $g_ = max(0, min($g_, 255));
811                                        $b_ = $b2 + 1 * ($b - 127);
812                                        $b_ = max(0, min($b_, 255));
813                                       
814                                        $a_ = $a + $a2 - round($a*$a2/127);
815                                }
816
817                                $color = ImageColorAllocateAlpha( $im_, $r_, $g_, $b_ , $a_ );
818                                imagesetpixel ($im_, $x, $y, $color);                   
819                        }
820                }
821
822                _image_gd_output($im_,$image);
823                imagedestroy($im_);
824                imagedestroy($im);
825                imagedestroy($im2);
826
827        }
828        $x_dest = largeur($dest);
829        $y_dest = hauteur($dest);
830        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>$x_dest,'height'=>$y_dest));
831}
832
833// Passage de l'image en noir et blanc
834// un noir & blanc "photo" n'est pas "neutre": les composantes de couleur sont
835// ponderees pour obtenir le niveau de gris;
836// on peut ici regler cette ponderation en "pour mille"
837// http://doc.spip.org/@image_nb
838function image_nb($im, $val_r = 299, $val_g = 587, $val_b = 114)
839{
840        $fonction = array('image_nb', func_get_args());
841        $image = _image_valeurs_trans($im, "nb-$val_r-$val_g-$val_b",false,$fonction);
842        if (!$image) return("");
843       
844        $x_i = $image["largeur"];
845        $y_i = $image["hauteur"];
846       
847        $im = $image["fichier"];
848        $dest = $image["fichier_dest"];
849       
850        $creer = $image["creer"];
851       
852        // Methode precise
853        // resultat plus beau, mais tres lourd
854        // Et: indispensable pour preserver transparence!
855
856        if ($creer) {
857                // Creation de l'image en deux temps
858                // de facon a conserver les GIF transparents
859                $im = $image["fonction_imagecreatefrom"]($im);
860                imagepalettetotruecolor($im);
861                $im_ = imagecreatetruecolor($x_i, $y_i);
862                @imagealphablending($im_, false);
863                @imagesavealpha($im_,true);
864                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
865                imagefill ($im_, 0, 0, $color_t);
866                imagecopy($im_, $im, 0, 0, 0, 0, $x_i, $y_i);
867               
868                for ($x = 0; $x < $x_i; $x++) {
869                        for ($y=0; $y < $y_i; $y++) {
870                                $rgb = ImageColorAt($im_, $x, $y);
871                                $a = ($rgb >> 24) & 0xFF;
872                                $r = ($rgb >> 16) & 0xFF;
873                                $g = ($rgb >> 8) & 0xFF;
874                                $b = $rgb & 0xFF;
875
876                                $c = round(($val_r * $r / 1000) + ($val_g * $g / 1000) + ($val_b * $b / 1000));
877                                if ($c < 0) $c = 0;
878                                if ($c > 254) $c = 254;
879                               
880                               
881                                $color = ImageColorAllocateAlpha( $im_, $c, $c, $c , $a );
882                                imagesetpixel ($im_, $x, $y, $color);                   
883                        }
884                }
885                _image_gd_output($im_,$image);
886                imagedestroy($im_);
887                imagedestroy($im);
888        }
889
890        return _image_ecrire_tag($image,array('src'=>$dest));
891}
892
893// http://doc.spip.org/@image_flou
894function image_flou($im,$niveau=3)
895{
896        // Il s'agit d'une modification du script blur qu'on trouve un peu partout:
897        // + la transparence est geree correctement
898        // + les dimensions de l'image sont augmentees pour flouter les bords
899        $coeffs = array (
900                                array ( 1),
901                                array ( 1, 1), 
902                                array ( 1, 2, 1),
903                                array ( 1, 3, 3, 1),
904                                array ( 1, 4, 6, 4, 1),
905                                array ( 1, 5, 10, 10, 5, 1),
906                                array ( 1, 6, 15, 20, 15, 6, 1),
907                                array ( 1, 7, 21, 35, 35, 21, 7, 1),
908                                array ( 1, 8, 28, 56, 70, 56, 28, 8, 1),
909                                array ( 1, 9, 36, 84, 126, 126, 84, 36, 9, 1),
910                                array ( 1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1),
911                                array ( 1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1)
912                                );
913       
914        $fonction = array('image_flou', func_get_args());
915        $image = _image_valeurs_trans($im, "flou-$niveau", false,$fonction);
916        if (!$image) return("");
917       
918        $x_i = $image["largeur"];
919        $y_i = $image["hauteur"];
920        $sum = pow (2, $niveau);
921
922        $im = $image["fichier"];
923        $dest = $image["fichier_dest"];
924       
925        $creer = $image["creer"];
926       
927        // Methode precise
928        // resultat plus beau, mais tres lourd
929        // Et: indispensable pour preserver transparence!
930
931        if ($creer) {
932                // Creation de l'image en deux temps
933                // de facon a conserver les GIF transparents
934                $im = $image["fonction_imagecreatefrom"]($im);
935                imagepalettetotruecolor($im);
936                $temp1 = imagecreatetruecolor($x_i+$niveau, $y_i);
937                $temp2 = imagecreatetruecolor($x_i+$niveau, $y_i+$niveau);
938               
939                @imagealphablending($temp1, false);
940                @imagesavealpha($temp1,true);
941                @imagealphablending($temp2, false);
942                @imagesavealpha($temp2,true);
943
944               
945                for ($i = 0; $i < $x_i+$niveau; $i++) {
946                        for ($j=0; $j < $y_i; $j++) {
947                                $suma=0;
948                                $sumr=0;
949                                $sumg=0;
950                                $sumb=0;
951                                $sum = 0;
952                                $sum_ = 0;
953                                for ( $k=0 ; $k <= $niveau ; ++$k ) {
954                                        $color = imagecolorat($im, $i_ = ($i-$niveau)+$k , $j);
955
956                                        $a = ($color >> 24) & 0xFF;
957                                        $r = ($color >> 16) & 0xFF;
958                                        $g = ($color >> 8) & 0xFF;
959                                        $b = ($color) & 0xFF;
960                                       
961                                        if ($i_ < 0 OR $i_ >= $x_i) $a = 127;
962                                       
963                                        $coef = $coeffs[$niveau][$k];
964                                        $suma += $a*$coef;
965                                        $ac = ((127-$a) / 127);
966                                       
967                                        $ac = $ac*$ac;
968                                       
969                                        $sumr += $r * $coef * $ac;
970                                        $sumg += $g * $coef * $ac;
971                                        $sumb += $b * $coef * $ac;
972                                        $sum += $coef * $ac;
973                                        $sum_ += $coef;
974                                }
975                                if ($sum > 0) $color = ImageColorAllocateAlpha ($temp1, $sumr/$sum, $sumg/$sum, $sumb/$sum, $suma/$sum_);
976                                else $color = ImageColorAllocateAlpha ($temp1, 255, 255, 255, 127);
977                                imagesetpixel($temp1,$i,$j,$color);
978                        }
979                }
980                imagedestroy($im);
981                for ($i = 0; $i < $x_i+$niveau; $i++) {
982                        for ($j=0; $j < $y_i+$niveau; $j++) {
983                                $suma=0;
984                                $sumr=0;
985                                $sumg=0;
986                                $sumb=0;
987                                $sum = 0;
988                                $sum_ = 0;
989                                for ( $k=0 ; $k <= $niveau ; ++$k ) {
990                                        $color = imagecolorat($temp1, $i, $j_ = $j-$niveau+$k);
991                                        $a = ($color >> 24) & 0xFF;
992                                        $r = ($color >> 16) & 0xFF;
993                                        $g = ($color >> 8) & 0xFF;
994                                        $b = ($color) & 0xFF;
995                                        if ($j_ < 0 OR $j_ >= $y_i) $a = 127;
996                                       
997                                        $suma += $a*$coeffs[$niveau][$k];
998                                        $ac = ((127-$a) / 127);
999                                                                               
1000                                        $sumr += $r * $coeffs[$niveau][$k] * $ac;
1001                                        $sumg += $g * $coeffs[$niveau][$k] * $ac;
1002                                        $sumb += $b * $coeffs[$niveau][$k] * $ac;
1003                                        $sum += $coeffs[$niveau][$k] * $ac;
1004                                        $sum_ += $coeffs[$niveau][$k];
1005                                       
1006                                }
1007                                if ($sum > 0) $color = ImageColorAllocateAlpha ($temp2, $sumr/$sum, $sumg/$sum, $sumb/$sum, $suma/$sum_);
1008                                else $color = ImageColorAllocateAlpha ($temp2, 255, 255, 255, 127);
1009                                imagesetpixel($temp2,$i,$j,$color);
1010                        }
1011                }
1012       
1013                _image_gd_output($temp2,$image);
1014                imagedestroy($temp1);   
1015                imagedestroy($temp2);   
1016        }
1017       
1018        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>($x_i+$niveau),'height'=>($y_i+$niveau)));
1019}
1020
1021// http://doc.spip.org/@image_RotateBicubic
1022function image_RotateBicubic($src_img, $angle, $bicubic=0) {
1023        include_spip('filtres/images_lib');
1024   
1025        if (round($angle/90)*90 == $angle) {
1026                $droit = true;
1027                if (round($angle/180)*180 == $angle) $rot = 180;
1028                else $rot = 90;
1029        }
1030        else 
1031                $droit = false;
1032   
1033        // convert degrees to radians
1034        $angle = $angle + 180;
1035        $angle = deg2rad($angle);
1036       
1037       
1038       
1039        $src_x = imagesx($src_img);
1040        $src_y = imagesy($src_img);
1041       
1042       
1043        $center_x = floor(($src_x-1)/2);
1044        $center_y = floor(($src_y-1)/2);
1045       
1046        $cosangle = cos($angle);
1047        $sinangle = sin($angle);
1048
1049        // calculer dimensions en simplifiant angles droits, ce qui evite "floutage"
1050        // des rotations a angle droit
1051        if (!$droit) {
1052                $corners=array(array(0,0), array($src_x,0), array($src_x,$src_y), array(0,$src_y));
1053       
1054                foreach($corners as $key=>$value) {
1055                        $value[0]-=$center_x;        //Translate coords to center for rotation
1056                        $value[1]-=$center_y;
1057                        $temp=array();
1058                        $temp[0]=$value[0]*$cosangle+$value[1]*$sinangle;
1059                        $temp[1]=$value[1]*$cosangle-$value[0]*$sinangle;
1060                        $corners[$key]=$temp;   
1061                }
1062           
1063                $min_x=1000000000000000;
1064                $max_x=-1000000000000000;
1065                $min_y=1000000000000000;
1066                $max_y=-1000000000000000;
1067           
1068                foreach($corners as $key => $value) {
1069                        if($value[0]<$min_x)
1070                                $min_x=$value[0];
1071                        if($value[0]>$max_x)
1072                                $max_x=$value[0];
1073                       
1074                        if($value[1]<$min_y)
1075                                $min_y=$value[1];
1076                        if($value[1]>$max_y)
1077                                $max_y=$value[1];
1078          }
1079       
1080                $rotate_width=ceil($max_x-$min_x);
1081                $rotate_height=ceil($max_y-$min_y);
1082        }
1083        else {
1084                if ($rot == 180) {
1085                        $rotate_height = $src_y;
1086                        $rotate_width = $src_x;
1087                } else {
1088                        $rotate_height = $src_x;
1089                        $rotate_width = $src_y;
1090                }
1091                $bicubic = false;
1092        }
1093       
1094       
1095        $rotate=imagecreatetruecolor($rotate_width,$rotate_height);
1096        imagealphablending($rotate, false);
1097        imagesavealpha($rotate, true);
1098       
1099        $cosangle = cos($angle);
1100        $sinangle = sin($angle);
1101   
1102        // arrondir pour rotations angle droit (car cos et sin dans {-1,0,1})
1103        if ($droit) {
1104                $cosangle = round($cosangle);
1105                $sinangle = round($sinangle);
1106        }
1107
1108        $newcenter_x = ($rotate_width-1)/2;
1109        $newcenter_y = ($rotate_height-1)/2;
1110
1111   
1112        for ($y = 0; $y < $rotate_height; $y++) {
1113                for ($x = 0; $x < $rotate_width; $x++) {
1114                        // rotate...
1115                        $old_x = ((($newcenter_x-$x) * $cosangle + ($newcenter_y-$y) * $sinangle))
1116                         + $center_x;
1117                        $old_y = ((($newcenter_y-$y) * $cosangle - ($newcenter_x-$x) * $sinangle))
1118                         + $center_y; 
1119         
1120                        $old_x = ceil($old_x);
1121                        $old_y = ceil($old_y);
1122         
1123                        if ( $old_x >= 0 && $old_x < $src_x
1124                         && $old_y >= 0 && $old_y < $src_y ) {
1125                                if ($bicubic == true) {
1126                                        $xo = $old_x;
1127                                        $x0 = floor($xo);
1128                                        $x1 = ceil($xo);
1129                                        $yo = $old_y;
1130                                        $y0 = floor($yo);
1131                                        $y1 = ceil($yo);
1132       
1133                                        // on prend chaque point, mais on pondere en fonction de la distance
1134                                        $rgb = ImageColorAt($src_img, $x0, $y0); 
1135                                        $a1 = ($rgb >> 24) & 0xFF;
1136                                        $r1 = ($rgb >> 16) & 0xFF;
1137                                        $g1 = ($rgb >> 8) & 0xFF;
1138                                        $b1 = $rgb & 0xFF;
1139                                        $d1 = _image_distance_pixel($xo, $yo, $x0, $y0);
1140                                       
1141                                        $rgb = ImageColorAt($src_img, $x1, $y0); 
1142                                        $a2 = ($rgb >> 24) & 0xFF;
1143                                        $r2 = ($rgb >> 16) & 0xFF;
1144                                        $g2 = ($rgb >> 8) & 0xFF;
1145                                        $b2 = $rgb & 0xFF;
1146                                        $d2 = _image_distance_pixel($xo, $yo, $x1, $y0);
1147                                       
1148                                        $rgb = ImageColorAt($src_img,$x0, $y1); 
1149                                        $a3 = ($rgb >> 24) & 0xFF;
1150                                        $r3 = ($rgb >> 16) & 0xFF;
1151                                        $g3 = ($rgb >> 8) & 0xFF;
1152                                        $b3 = $rgb & 0xFF;
1153                                        $d3 = _image_distance_pixel($xo, $yo, $x0, $y1);
1154                                       
1155                                        $rgb = ImageColorAt($src_img,$x1, $y1);
1156                                        $a4 = ($rgb >> 24) & 0xFF;
1157                                        $r4 = ($rgb >> 16) & 0xFF;
1158                                        $g4 = ($rgb >> 8) & 0xFF;
1159                                        $b4 = $rgb & 0xFF;
1160                                        $d4 = _image_distance_pixel($xo, $yo, $x1, $y1);
1161                                       
1162                                        $ac1 = ((127-$a1) / 127);
1163                                        $ac2 = ((127-$a2) / 127);
1164                                        $ac3 = ((127-$a3) / 127);
1165                                        $ac4 = ((127-$a4) / 127);
1166
1167                                        // limiter impact des couleurs transparentes,
1168                                        // mais attention tout transp: division par 0
1169                                        if ($ac1*$d1 + $ac2*$d2 + $ac3+$d3 + $ac4+$d4 > 0) {
1170                                                if ($ac1 > 0) $d1 = $d1 * $ac1;
1171                                                if ($ac2 > 0) $d2 = $d2 * $ac2;
1172                                                if ($ac3 > 0) $d3 = $d3 * $ac3;
1173                                                if ($ac4 > 0) $d4 = $d4 * $ac4;
1174                                        }
1175                                       
1176                                        $tot  = $d1 + $d2 + $d3 + $d4;
1177
1178                                        $r = round((($d1*$r1)+($d2*$r2)+($d3*$r3)+($d4*$r4))/$tot);
1179                                        $g = round((($d1*$g1+($d2*$g2)+$d3*$g3+$d4*$g4))/$tot);
1180                                        $b = round((($d1*$b1+($d2*$b2)+$d3*$b3+$d4*$b4))/$tot);
1181                                        $a = round((($d1*$a1+($d2*$a2)+$d3*$a3+$d4*$a4))/$tot);
1182                                        $color = imagecolorallocatealpha($src_img, $r,$g,$b,$a);
1183                                } 
1184                                else {
1185                                        $color = imagecolorat($src_img, round($old_x), round($old_y));
1186                                }
1187                        }
1188                        else {
1189                                // this line sets the background colour
1190                                $color = imagecolorallocatealpha($src_img, 255, 255, 255, 127);
1191                        }
1192                        @imagesetpixel($rotate, $x, $y, $color);
1193                }
1194        }
1195        return $rotate;
1196}
1197
1198// permet de faire tourner une image d'un angle quelconque
1199// la fonction "crop" n'est pas implementee...
1200// http://doc.spip.org/@image_rotation
1201function image_rotation($im, $angle, $crop=false)
1202{
1203        $fonction = array('image_rotation', func_get_args());
1204        $image = _image_valeurs_trans($im, "rot-$angle-$crop", "png", $fonction);
1205        if (!$image) return("");
1206       
1207        $im = $image["fichier"];
1208        $dest = $image["fichier_dest"];
1209       
1210        $creer = $image["creer"];
1211       
1212        if ($creer) {
1213                $effectuer_gd = true;
1214
1215                if(is_callable(array('Imagick','rotateImage'))){
1216                        $imagick = new Imagick();
1217                        $imagick->readImage($im);
1218                        $imagick->rotateImage(new ImagickPixel('none'), $angle);
1219                        $imagick->writeImage($dest);
1220                        $effectuer_gd = false;
1221                }
1222                else if ($GLOBALS['meta']['image_process'] == "convert") {
1223                        if (_CONVERT_COMMAND!='') {
1224                                @define ('_CONVERT_COMMAND', 'convert');
1225                                @define ('_ROTATE_COMMAND', _CONVERT_COMMAND.' -background none -rotate %t %src %dest');
1226                        } else
1227                                @define ('_ROTATE_COMMAND', '');
1228                        if (_ROTATE_COMMAND!=='') {
1229                                $commande = str_replace(
1230                                        array('%t', '%src', '%dest'),
1231                                        array(
1232                                                $angle,
1233                                                escapeshellcmd($im),
1234                                                escapeshellcmd($dest)
1235                                        ),
1236                                        _ROTATE_COMMAND);
1237                                spip_log($commande);
1238                                exec($commande);
1239                                if (file_exists($dest)) // precaution
1240                                        $effectuer_gd = false;
1241                        }
1242                }
1243                // cette variante genere-t-elle un fond transparent
1244                // dans les coins vide issus de la rotation ?
1245                elseif (function_exists('imagick_rotate')) {
1246                        $handle = imagick_readimage ($im);
1247                        if ($handle && imagick_isopaqueimage( $handle )) {
1248                                imagick_setfillcolor($handle, 'transparent');
1249                                imagick_rotate( $handle, $angle);
1250                                imagick_writeimage( $handle, $dest);
1251                                $effectuer_gd = false;
1252                        }
1253                }
1254                if ($effectuer_gd) {
1255                        // Creation de l'image en deux temps
1256                        // de facon a conserver les GIF transparents
1257                        $im = $image["fonction_imagecreatefrom"]($im);
1258                        imagepalettetotruecolor($im);
1259                        $im = image_RotateBicubic($im, $angle, true);
1260                        _image_gd_output($im,$image);
1261                        imagedestroy($im);
1262                }
1263        }
1264        list ($src_y,$src_x) = taille_image($dest);
1265        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>$src_x,'height'=>$src_y));
1266}
1267
1268// Permet d'appliquer un filtre php_imagick a une image
1269// par exemple: [(#LOGO_ARTICLE|image_imagick{imagick_wave,20,60})]
1270// liste des fonctions: http://www.linux-nantes.org/~fmonnier/doc/imagick/
1271// http://doc.spip.org/@image_imagick
1272function image_imagick () {
1273        $tous = func_get_args();
1274        $img = $tous[0];
1275        $fonc = $tous[1];
1276        $tous[0]="";
1277        $tous_var = join($tous, "-");
1278
1279        $fonction = array('image_imagick', func_get_args());
1280        $image = _image_valeurs_trans($img, "$tous_var", "png",$fonction);
1281        if (!$image) return("");
1282       
1283        $im = $image["fichier"];
1284        $dest = $image["fichier_dest"];
1285       
1286        $creer = $image["creer"];
1287       
1288        if ($creer) {
1289                if (function_exists($fonc)) {
1290
1291                        $handle = imagick_readimage ($im);
1292                        $arr[0] = $handle;
1293                        for ($i=2; $i < count($tous); $i++) $arr[] = $tous[$i];
1294                        call_user_func_array($fonc, $arr);
1295                        // Creer image dans fichier temporaire, puis renommer vers "bon" fichier
1296                        // de facon a eviter time_out pendant creation de l'image definitive
1297                        $tmp = preg_replace(",[.]png$,i", "-tmp.png", $dest);
1298                        imagick_writeimage( $handle, $tmp);
1299                        rename($tmp, $dest);
1300                        ecrire_fichier($dest.".src",serialize($image));
1301                } 
1302        }
1303        list ($src_y,$src_x) = taille_image($dest);
1304        return _image_ecrire_tag($image,array('src'=>$dest,'width'=>$src_x,'height'=>$src_y));
1305
1306}
1307
1308// Permet de rendre une image
1309// plus claire (gamma > 0)
1310// ou plus foncee (gamma < 0)
1311// http://doc.spip.org/@image_gamma
1312function image_gamma($im, $gamma = 0){
1313        include_spip('filtres/images_lib');
1314        $fonction = array('image_gamma', func_get_args());
1315        $image = _image_valeurs_trans($im, "gamma-$gamma",false,$fonction);
1316        if (!$image) return("");
1317       
1318        $x_i = $image["largeur"];
1319        $y_i = $image["hauteur"];
1320       
1321        $im = $image["fichier"];
1322        $dest = $image["fichier_dest"];
1323       
1324        $creer = $image["creer"];
1325       
1326        if ($creer) {
1327                // Creation de l'image en deux temps
1328                // de facon a conserver les GIF transparents
1329                $im = $image["fonction_imagecreatefrom"]($im);
1330                imagepalettetotruecolor($im);
1331                $im_ = imagecreatetruecolor($x_i, $y_i);
1332                @imagealphablending($im_, false);
1333                @imagesavealpha($im_,true);
1334                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
1335                imagefill ($im_, 0, 0, $color_t);
1336                imagecopy($im_, $im, 0, 0, 0, 0, $x_i, $y_i);
1337       
1338                for ($x = 0; $x < $x_i; $x++) {
1339                        for ($y=0; $y < $y_i; $y++) {
1340                                $rgb = ImageColorAt($im_, $x, $y);
1341                                $a = ($rgb >> 24) & 0xFF;
1342                                $r = ($rgb >> 16) & 0xFF;
1343                                $g = ($rgb >> 8) & 0xFF;
1344                                $b = $rgb & 0xFF;
1345
1346                                $r = _image_decale_composante($r, $gamma);
1347                                $g = _image_decale_composante($g, $gamma);
1348                                $b = _image_decale_composante($b, $gamma);
1349
1350                                $color = ImageColorAllocateAlpha( $im_, $r, $g, $b , $a );
1351                                imagesetpixel ($im_, $x, $y, $color);                   
1352                        }
1353                }
1354                _image_gd_output($im_,$image);
1355        }
1356        return _image_ecrire_tag($image,array('src'=>$dest));
1357}
1358
1359// Passe l'image en "sepia"
1360// On peut fixer les valeurs RGB
1361// de la couleur "complementaire" pour forcer une dominante
1362//function image_sepia($im, $dr = 137, $dv = 111, $db = 94)
1363// http://doc.spip.org/@image_sepia
1364function image_sepia($im, $rgb = "896f5e"){
1365        include_spip('filtres/images_lib');
1366       
1367        if (!function_exists("imagecreatetruecolor")) return $im;
1368       
1369        $couleurs = _couleur_hex_to_dec($rgb);
1370        $dr= $couleurs["red"];
1371        $dv= $couleurs["green"];
1372        $db= $couleurs["blue"];
1373               
1374        $fonction = array('image_sepia', func_get_args());
1375        $image = _image_valeurs_trans($im, "sepia-$dr-$dv-$db",false,$fonction);
1376        if (!$image) return("");
1377       
1378        $x_i = $image["largeur"];
1379        $y_i = $image["hauteur"];
1380       
1381        $im = $image["fichier"];
1382        $dest = $image["fichier_dest"];
1383       
1384        $creer = $image["creer"];
1385       
1386        if ($creer) {
1387                // Creation de l'image en deux temps
1388                // de facon a conserver les GIF transparents
1389                $im = $image["fonction_imagecreatefrom"]($im);
1390                imagepalettetotruecolor($im);
1391                $im_ = imagecreatetruecolor($x_i, $y_i);
1392                @imagealphablending($im_, false);
1393                @imagesavealpha($im_,true);
1394                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
1395                imagefill ($im_, 0, 0, $color_t);
1396                imagecopy($im_, $im, 0, 0, 0, 0, $x_i, $y_i);
1397       
1398                for ($x = 0; $x < $x_i; $x++) {
1399                        for ($y=0; $y < $y_i; $y++) {
1400                                $rgb = ImageColorAt($im_, $x, $y);
1401                                $a = ($rgb >> 24) & 0xFF;
1402                                $r = ($rgb >> 16) & 0xFF;
1403                                $g = ($rgb >> 8) & 0xFF;
1404                                $b = $rgb & 0xFF;
1405
1406                                $r = round(.299 * $r + .587 * $g + .114 * $b);
1407                                $g = $r;
1408                                $b = $r;
1409
1410
1411                                $r = _image_decale_composante_127($r, $dr);
1412                                $g = _image_decale_composante_127($g, $dv);
1413                                $b = _image_decale_composante_127($b, $db);
1414
1415                                $color = ImageColorAllocateAlpha( $im_, $r, $g, $b , $a );
1416                                imagesetpixel ($im_, $x, $y, $color);                   
1417                        }
1418                }
1419                _image_gd_output($im_,$image);
1420                imagedestroy($im_);
1421                imagedestroy($im);
1422        }
1423       
1424        return _image_ecrire_tag($image,array('src'=>$dest));
1425}
1426
1427
1428// Renforcer la nettete d'une image
1429// http://doc.spip.org/@image_renforcement
1430function image_renforcement($im, $k=0.5)
1431{
1432        $fonction = array('image_flou', func_get_args());
1433        $image = _image_valeurs_trans($im, "renforcement-$k",false,$fonction);
1434        if (!$image) return("");
1435       
1436        $x_i = $image["largeur"];
1437        $y_i = $image["hauteur"];
1438        $im = $image["fichier"];
1439        $dest = $image["fichier_dest"];
1440        $creer = $image["creer"];
1441       
1442        if ($creer) {
1443                $im = $image["fonction_imagecreatefrom"]($im);
1444                imagepalettetotruecolor($im);
1445                $im_ = imagecreatetruecolor($x_i, $y_i);
1446                @imagealphablending($im_, false);
1447                @imagesavealpha($im_,true);
1448                $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
1449                imagefill ($im_, 0, 0, $color_t);
1450
1451                for ($x = 0; $x < $x_i; $x++) {
1452                        for ($y=0; $y < $y_i; $y++) {           
1453
1454                $rgb[1][0]=imagecolorat($im,$x,$y-1);
1455                $rgb[0][1]=imagecolorat($im,$x-1,$y);
1456                $rgb[1][1]=imagecolorat($im,$x,$y);
1457                $rgb[2][1]=imagecolorat($im,$x+1,$y);
1458                $rgb[1][2]=imagecolorat($im,$x,$y+1);
1459               
1460               
1461                if ($x-1 < 0) $rgb[0][1] = $rgb[1][1];
1462                if ($y-1 < 0) $rgb[1][0] = $rgb[1][1];
1463                if ($x+1 == $x_i) $rgb[2][1] = $rgb[1][1];
1464                if ($y+1 == $y_i) $rgb[1][2] = $rgb[1][1];
1465
1466                $a = ($rgb[1][1] >> 24) & 0xFF;
1467                $r = -$k *(($rgb[1][0] >> 16) & 0xFF) +
1468                         -$k *(($rgb[0][1] >> 16) & 0xFF) +
1469                        (1+4*$k) *(($rgb[1][1] >> 16) & 0xFF) +
1470                         -$k *(($rgb[2][1] >> 16) & 0xFF) +
1471                         -$k *(($rgb[1][2] >> 16) & 0xFF) ;
1472
1473                $g = -$k *(($rgb[1][0] >> 8) & 0xFF) +
1474                         -$k *(($rgb[0][1] >> 8) & 0xFF) +
1475                         (1+4*$k) *(($rgb[1][1] >> 8) & 0xFF) +
1476                         -$k *(($rgb[2][1] >> 8) & 0xFF) +
1477                         -$k *(($rgb[1][2] >> 8) & 0xFF) ;
1478
1479                $b = -$k *($rgb[1][0] & 0xFF) +
1480                         -$k *($rgb[0][1] & 0xFF) +
1481                        (1+4*$k) *($rgb[1][1] & 0xFF) +
1482                         -$k *($rgb[2][1] & 0xFF) +
1483                         -$k *($rgb[1][2] & 0xFF) ;
1484
1485                $r=min(255,max(0,$r));
1486                $g=min(255,max(0,$g));
1487                $b=min(255,max(0,$b));
1488
1489
1490                $color = ImageColorAllocateAlpha( $im_, $r, $g, $b , $a );
1491                imagesetpixel ($im_, $x, $y, $color);                   
1492                        }
1493                }               
1494                _image_gd_output($im_,$image);
1495        }
1496
1497        return _image_ecrire_tag($image,array('src'=>$dest));
1498}
1499
1500
1501
1502
1503//
1504// alpha = 0: aucune transparence
1505// alpha = 127: completement transparent
1506/**
1507 * Transforme la couleur de fond de l'image en transparence
1508 * Le filtre ne g�re pas la notion de contiguite aux bords, et affectera tous les pixels de l'image dans la couleur visee
1509 * $background_color : couleur cible
1510 * $tolerance : distance L1 dans l'espace RGB des couleur autour de la couleur $background_color pour lequel la transparence sera appliquee
1511 * $alpha : transparence a appliquer pour les pixels de la couleur cibles avec la tolerance ci-dessus
1512 * $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
1513 *
1514 * @param string $im
1515 * @param string $background_color
1516 * @param int $tolerance
1517 * @param int $alpha
1518 * @param float $coeff_lissage
1519 * @return string
1520 */
1521function image_fond_transparent($im, $background_color, $tolerance=12, $alpha = 127, $coeff_lissage=7)
1522{
1523        $fonction = array('image_fond_transparent', func_get_args());
1524        $image = _image_valeurs_trans($im, "fond_transparent-$background_color-$tolerance-$coeff_lissage-$alpha", "png", $fonction);
1525        if (!$image) return("");
1526       
1527        $x_i = $image["largeur"];
1528        $y_i = $image["hauteur"];
1529       
1530        $im = $image["fichier"];
1531        $dest = $image["fichier_dest"];
1532       
1533        $creer = $image["creer"];
1534       
1535        if (true OR $creer) {
1536                $bg = _couleur_hex_to_dec($background_color);
1537                $bg_r = $bg['red'];
1538                $bg_g = $bg['green'];
1539                $bg_b = $bg['blue'];
1540       
1541                // Creation de l'image en deux temps
1542                // de facon a conserver les GIF transparents
1543                $im = $image["fonction_imagecreatefrom"]($im);
1544                imagepalettetotruecolor($im);
1545                $im2 = imagecreatetruecolor($x_i, $y_i);
1546                @imagealphablending($im2, false);
1547                @imagesavealpha($im2,true);
1548                $color_t = ImageColorAllocateAlpha( $im2, 255, 255, 255 , 127 );
1549                imagefill ($im2, 0, 0, $color_t);
1550                imagecopy($im2, $im, 0, 0, 0, 0, $x_i, $y_i);
1551
1552                $im_ = imagecreatetruecolor($x_i, $y_i);
1553                imagealphablending ($im_, FALSE );
1554                imagesavealpha ( $im_, TRUE );
1555                $color_f = ImageColorAllocateAlpha( $im_, 255, 255, 255 , $alpha );
1556
1557                for ($x = 0; $x < $x_i; $x++) {
1558                        for ($y = 0; $y < $y_i; $y++) {
1559                                $rgb = ImageColorAt($im2, $x, $y);
1560                                $r = ($rgb >> 16) & 0xFF;
1561                                $g = ($rgb >> 8) & 0xFF;
1562                                $b = $rgb & 0xFF;
1563                                if ((($d=abs($r-$bg_r)+abs($g-$bg_g)+abs($b-$bg_b))<=$tolerance)){
1564                                        imagesetpixel ( $im_, $x, $y, $color_f );
1565                                }
1566                                elseif ($tolerance AND $d<=($coeff_lissage+1)*$tolerance){
1567                                        $transp = round($alpha*(1-($d-$tolerance)/($coeff_lissage*$tolerance)));
1568                                        $color_p = ImageColorAllocateAlpha( $im_, $r, $g, $b , $transp);                                       
1569                                        imagesetpixel ( $im_, $x, $y, $color_p );
1570                                }
1571                                else
1572                                        imagesetpixel ( $im_, $x, $y, $rgb );
1573                        }
1574                }
1575                _image_gd_output($im_,$image);
1576                imagedestroy($im_);
1577                imagedestroy($im);
1578                imagedestroy($im2);
1579        }
1580       
1581        return _image_ecrire_tag($image,array('src'=>$dest));
1582}
1583?>
Note: See TracBrowser for help on using the repository browser.