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

Last change on this file since 93466 was 93466, checked in by marcimat@…, 5 years ago

On permet à la fonction image_recadre d'avoir d'autres solutions de positionnement
que celles par défaut (center, top, left, right, bottom, ou des mélanges "top left" ou des valeurs "top=30")
en indiquant un nom spécifique, tel que focus, ce qui cherchera alors une fonction
inc_image_positionner_par_focus_dist() (en utilisant charger_fonction()). Si une telle fonction
existe, elle est appelée en transmettant l'image reçue, ainsi que la largeur et hauteur de destination désirée.
Elle doit alors retourner le positionnement souhaité pour le recadrage, tel que "top=230 left=300".

Cette extension 'focus' (et 'focus-center') va être définie dans le plugin Centre Image.
C'est le même procédé (et même nommage) que ce qui est dans le plugin Image Responsive à travers
la fonction |image_proportions de ce plugin. Sauf qu'ici, on utilise la fonction habituelle
de SPIP |image_recadre (et donc il ne sera pas nécessaire d'avoir le plugin Image Responsive actif,
mais c'est tout à fait possible évidemment !).

Cela permet donc ce type d'écriture (ce qui recadrera l'image sur le point d'intérêt si le plugin Centre Image est présent) :

[(#LOGO_ARTICLE|image_recadre{200:100, -, focus}|image_reduire{200, 100})]

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