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

Last change on this file was 113294, checked in by spip.franck@…, 2 months ago

Il parait que le futur c'est maintenant :-D

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