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

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

Sécurité : éviter un full path disclosure (High-Tech Bridge Security Research Lab)

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