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