2 /***************************************************************************\
3 * SPIP, Systeme de publication pour l'internet *
5 * Copyright (c) 2001-2020 *
6 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
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 \***************************************************************************/
12 if (!defined('_ECRIRE_INC_VERSION')) {
16 // librairie de base du core
17 include_spip('inc/filtres_images_lib_mini');
19 function multiple_de_trois($val) {
20 return intval(round($val / 3) * 3);
24 * Transformation d'une couleur vectorielle RGB en HSV
25 * RGB entiers entre 0 et 255
26 * HSV float entre 0 et 1
33 function _couleur_rgb2hsv($R, $G, $B) {
34 $var_R = ($R / 255); //Where RGB values = 0 ÷ 255
38 $var_Min = min($var_R, $var_G, $var_B); //Min. value of RGB
39 $var_Max = max($var_R, $var_G, $var_B); //Max. value of RGB
40 $del_Max = $var_Max - $var_Min; //Delta RGB value
43 $L = ($var_Max +
$var_Min) / 2;
45 if ($del_Max == 0) //This is a gray, no chroma...
47 $H = 0; //HSL results = 0 ÷ 1
49 } else //Chromatic data...
51 $S = $del_Max / $var_Max;
53 $del_R = ((($var_Max - $var_R) / 6) +
($del_Max / 2)) / $del_Max;
54 $del_G = ((($var_Max - $var_G) / 6) +
($del_Max / 2)) / $del_Max;
55 $del_B = ((($var_Max - $var_B) / 6) +
($del_Max / 2)) / $del_Max;
57 if ($var_R == $var_Max) {
60 if ($var_G == $var_Max) {
61 $H = (1 / 3) +
$del_R - $del_B;
63 if ($var_B == $var_Max) {
64 $H = (2 / 3) +
$del_G - $del_R;
85 * Transformation d'une couleur vectorielle HSV en RGB
86 * HSV float entre 0 et 1
87 * RGB entiers entre 0 et 255
94 function _couleur_hsv2rgb($H, $S, $V) {
96 if ($S == 0) //HSV values = 0 ÷ 1
106 $var_i = floor($var_h); //Or ... var_i = floor( var_h )
107 $var_1 = $V * (1 - $S);
108 $var_2 = $V * (1 - $S * ($var_h - $var_i));
109 $var_3 = $V * (1 - $S * (1 - ($var_h - $var_i)));
146 $R = $var_r * 255; //RGB results = 0 ÷ 255
150 $ret["r"] = floor($R);
151 $ret["g"] = floor($G);
152 $ret["b"] = floor($B);
159 * Transformation d'une couleur RGB en HSL
160 * HSL float entre 0 et 1
161 * RGB entiers entre 0 et 255
168 function _couleur_rgb2hsl($R, $G, $B) {
169 $var_R = ($R / 255); //Where RGB values = 0 ÷ 255
173 $var_Min = min($var_R, $var_G, $var_B); //Min. value of RGB
174 $var_Max = max($var_R, $var_G, $var_B); //Max. value of RGB
175 $del_Max = $var_Max - $var_Min; //Delta RGB value
177 $L = ($var_Max +
$var_Min) / 2;
179 if ($del_Max == 0) //This is a gray, no chroma...
181 $H = 0; //HSL results = 0 ÷ 1
183 } else //Chromatic data...
186 $S = $del_Max / ($var_Max +
$var_Min);
188 $S = $del_Max / (2 - $var_Max - $var_Min);
191 $del_R = ((($var_Max - $var_R) / 6) +
($del_Max / 2)) / $del_Max;
192 $del_G = ((($var_Max - $var_G) / 6) +
($del_Max / 2)) / $del_Max;
193 $del_B = ((($var_Max - $var_B) / 6) +
($del_Max / 2)) / $del_Max;
195 if ($var_R == $var_Max) {
196 $H = $del_B - $del_G;
198 if ($var_G == $var_Max) {
199 $H = (1 / 3) +
$del_R - $del_B;
201 if ($var_B == $var_Max) {
202 $H = (2 / 3) +
$del_G - $del_R;
223 * Calcul d'une composante R, G ou B
225 * @param unknown_type $v1
226 * @param unknown_type $v2
227 * @param unknown_type $vH
230 function hue_2_rgb($v1, $v2, $vH) {
238 return ($v1 +
($v2 - $v1) * 6 * $vH);
244 return ($v1 +
($v2 - $v1) * ((2 / 3) - $vH) * 6);
252 * Transformation d'une couleur HSL en RGB
253 * HSL float entre 0 et 1
254 * RGB entiers entre 0 et 255
261 function _couleur_hsl2rgb($H, $S, $L) {
263 if ($S == 0) //HSV values = 0 -> 1
270 $var_2 = $L * (1 +
$S);
272 $var_2 = ($L +
$S) - ($S * $L);
275 $var_1 = 2 * $L - $var_2;
277 $R = 255 * hue_2_rgb($var_1, $var_2, $H +
(1 / 3));
278 $G = 255 * hue_2_rgb($var_1, $var_2, $H);
279 $B = 255 * hue_2_rgb($var_1, $var_2, $H - (1 / 3));
281 $ret["r"] = floor($R);
282 $ret["g"] = floor($G);
283 $ret["b"] = floor($B);
288 // A partir d'une image,
289 // recupere une couleur
290 // renvoit sous la forme hexadecimale ("F26C4E" par exemple).
291 // Par defaut, la couleur choisie se trouve un peu au-dessus du centre de l'image.
292 // On peut forcer un point en fixant $x et $y, entre 0 et 20.
293 // https://code.spip.net/@image_couleur_extraire
295 function _image_couleur_extraire($img, $x = 10, $y = 6) {
296 static $couleur_extraite = array();
298 if (isset($couleur_extraite["$img-$x-$y"])) {
299 return $couleur_extraite["$img-$x-$y"];
302 // valeur par defaut si l'image ne peut etre lue
305 $cache = _image_valeurs_trans($img, "coul-$x-$y", "txt");
307 return $couleur_extraite["$img-$x-$y"] = $defaut;
311 $fichier = $cache["fichier"];
312 $dest = $cache["fichier_dest"];
314 if (isset($couleur_extraite["$fichier-$x-$y"])) {
315 return $couleur_extraite["$fichier-$x-$y"];
318 $creer = $cache["creer"];
321 if (@file_exists
($fichier)) {
322 $width = $cache["largeur"];
323 $height = $cache["hauteur"];
328 $thumb = imagecreate($newwidth, $newheight);
330 $source = $cache["fonction_imagecreatefrom"]($fichier);
332 imagepalettetotruecolor($source);
334 imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
338 $color_index = imagecolorat($thumb, $x, $y);
340 // make it human readable
341 $color_tran = imagecolorsforindex($thumb, $color_index);
344 } while ($color_tran['alpha'] == 127 and $x < $newwidth and $y < $newheight);
346 $couleur = _couleur_dec_to_hex($color_tran["red"], $color_tran["green"], $color_tran["blue"]);
351 // Mettre en cache le resultat
352 $couleur_extraite["$fichier-$x-$y"] = $couleur;
353 ecrire_fichier($dest, $couleur_extraite["$fichier-$x-$y"]);
355 lire_fichier($dest, $couleur_extraite["$fichier-$x-$y"]);
358 return $couleur_extraite["$img-$x-$y"] = $couleur_extraite["$fichier-$x-$y"];
361 // $src_img - a GD image resource
362 // $angle - degrees to rotate clockwise, in degrees
363 // returns a GD image resource
364 // script de php.net lourdement corrig'e
365 // (le bicubic deconnait completement,
366 // et j'ai ajoute la ponderation par la distance au pixel)
367 function _image_distance_pixel($xo, $yo, $x0, $y0) {
370 $d = 1 - (sqrt(($vx) * ($vx) +
($vy) * ($vy)) / sqrt(2));
377 * Decale une composante de couleur
384 function _image_decale_composante($coul, $gamma) {
385 $coul = $coul +
$gamma;
398 * Decalage d'une composante de couleur en sepia
405 function _image_decale_composante_127($coul, $val) {
407 $y = round((($coul - 127) / 127) * $val) +
$val;
410 $y = round((($coul - 127) / 128) * (255 - $val)) +
$val;