[SPIP] v3.2.1-->v3.2.3
[lhc/web/www.git] / www / plugins-dist / filtres_images / filtres / images_lib.php
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 if (!defined('_ECRIRE_INC_VERSION')) {
13 return;
14 }
15
16 // librairie de base du core
17 include_spip('inc/filtres_images_lib_mini');
18
19 function multiple_de_trois($val) {
20 return intval(round($val / 3) * 3);
21 }
22
23 /**
24 * Transformation d'une couleur vectorielle RGB en HSV
25 * RGB entiers entre 0 et 255
26 * HSV float entre 0 et 1
27 *
28 * @param int $R
29 * @param int $G
30 * @param int $B
31 * @return array
32 */
33 function _couleur_rgb2hsv($R, $G, $B) {
34 $var_R = ($R / 255); //Where RGB values = 0 ÷ 255
35 $var_G = ($G / 255);
36 $var_B = ($B / 255);
37
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
41
42 $V = $var_Max;
43 $L = ($var_Max + $var_Min) / 2;
44
45 if ($del_Max == 0) //This is a gray, no chroma...
46 {
47 $H = 0; //HSL results = 0 ÷ 1
48 $S = 0;
49 } else //Chromatic data...
50 {
51 $S = $del_Max / $var_Max;
52
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;
56
57 if ($var_R == $var_Max) {
58 $H = $del_B - $del_G;
59 } else {
60 if ($var_G == $var_Max) {
61 $H = (1 / 3) + $del_R - $del_B;
62 } else {
63 if ($var_B == $var_Max) {
64 $H = (2 / 3) + $del_G - $del_R;
65 }
66 }
67 }
68
69 if ($H < 0) {
70 $H = $H + 1;
71 }
72 if ($H > 1) {
73 $H = $H - 1;
74 }
75 }
76
77 $ret["h"] = $H;
78 $ret["s"] = $S;
79 $ret["v"] = $V;
80
81 return $ret;
82 }
83
84 /**
85 * Transformation d'une couleur vectorielle HSV en RGB
86 * HSV float entre 0 et 1
87 * RGB entiers entre 0 et 255
88 *
89 * @param float $H
90 * @param float $S
91 * @param float $V
92 * @return array
93 */
94 function _couleur_hsv2rgb($H, $S, $V) {
95
96 if ($S == 0) //HSV values = 0 ÷ 1
97 {
98 $R = $V * 255;
99 $G = $V * 255;
100 $B = $V * 255;
101 } else {
102 $var_h = $H * 6;
103 if ($var_h == 6) {
104 $var_h = 0;
105 } //H must be < 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)));
110
111
112 if ($var_i == 0) {
113 $var_r = $V;
114 $var_g = $var_3;
115 $var_b = $var_1;
116 } else {
117 if ($var_i == 1) {
118 $var_r = $var_2;
119 $var_g = $V;
120 $var_b = $var_1;
121 } else {
122 if ($var_i == 2) {
123 $var_r = $var_1;
124 $var_g = $V;
125 $var_b = $var_3;
126 } else {
127 if ($var_i == 3) {
128 $var_r = $var_1;
129 $var_g = $var_2;
130 $var_b = $V;
131 } else {
132 if ($var_i == 4) {
133 $var_r = $var_3;
134 $var_g = $var_1;
135 $var_b = $V;
136 } else {
137 $var_r = $V;
138 $var_g = $var_1;
139 $var_b = $var_2;
140 }
141 }
142 }
143 }
144 }
145
146 $R = $var_r * 255; //RGB results = 0 ÷ 255
147 $G = $var_g * 255;
148 $B = $var_b * 255;
149 }
150 $ret["r"] = floor($R);
151 $ret["g"] = floor($G);
152 $ret["b"] = floor($B);
153
154 return $ret;
155 }
156
157
158 /**
159 * Transformation d'une couleur RGB en HSL
160 * HSL float entre 0 et 1
161 * RGB entiers entre 0 et 255
162 *
163 * @param int $R
164 * @param int $G
165 * @param int $B
166 * @return array
167 */
168 function _couleur_rgb2hsl($R, $G, $B) {
169 $var_R = ($R / 255); //Where RGB values = 0 ÷ 255
170 $var_G = ($G / 255);
171 $var_B = ($B / 255);
172
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
176
177 $L = ($var_Max + $var_Min) / 2;
178
179 if ($del_Max == 0) //This is a gray, no chroma...
180 {
181 $H = 0; //HSL results = 0 ÷ 1
182 $S = 0;
183 } else //Chromatic data...
184 {
185 if ($L < 0.5) {
186 $S = $del_Max / ($var_Max + $var_Min);
187 } else {
188 $S = $del_Max / (2 - $var_Max - $var_Min);
189 }
190
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;
194
195 if ($var_R == $var_Max) {
196 $H = $del_B - $del_G;
197 } else {
198 if ($var_G == $var_Max) {
199 $H = (1 / 3) + $del_R - $del_B;
200 } else {
201 if ($var_B == $var_Max) {
202 $H = (2 / 3) + $del_G - $del_R;
203 }
204 }
205 }
206
207 if ($H < 0) {
208 $H += 1;
209 }
210 if ($H > 1) {
211 $H -= 1;
212 }
213 }
214
215 $ret["h"] = $H;
216 $ret["s"] = $S;
217 $ret["l"] = $L;
218
219 return $ret;
220 }
221
222 /**
223 * Calcul d'une composante R, G ou B
224 *
225 * @param unknown_type $v1
226 * @param unknown_type $v2
227 * @param unknown_type $vH
228 * @return float
229 */
230 function hue_2_rgb($v1, $v2, $vH) {
231 if ($vH < 0) {
232 $vH += 1;
233 }
234 if ($vH > 1) {
235 $vH -= 1;
236 }
237 if ((6 * $vH) < 1) {
238 return ($v1 + ($v2 - $v1) * 6 * $vH);
239 }
240 if ((2 * $vH) < 1) {
241 return ($v2);
242 }
243 if ((3 * $vH) < 2) {
244 return ($v1 + ($v2 - $v1) * ((2 / 3) - $vH) * 6);
245 }
246
247 return ($v1);
248 }
249
250
251 /**
252 * Transformation d'une couleur HSL en RGB
253 * HSL float entre 0 et 1
254 * RGB entiers entre 0 et 255
255 *
256 * @param float $H
257 * @param float $S
258 * @param float $L
259 * @return array
260 */
261 function _couleur_hsl2rgb($H, $S, $L) {
262
263 if ($S == 0) //HSV values = 0 -> 1
264 {
265 $R = $L * 255;
266 $G = $L * 255;
267 $B = $L * 255;
268 } else {
269 if ($L < 0.5) {
270 $var_2 = $L * (1 + $S);
271 } else {
272 $var_2 = ($L + $S) - ($S * $L);
273 }
274
275 $var_1 = 2 * $L - $var_2;
276
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));
280 }
281 $ret["r"] = floor($R);
282 $ret["g"] = floor($G);
283 $ret["b"] = floor($B);
284
285 return $ret;
286 }
287
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
294
295 function _image_couleur_extraire($img, $x = 10, $y = 6) {
296 static $couleur_extraite = array();
297
298 if (isset($couleur_extraite["$img-$x-$y"])) {
299 return $couleur_extraite["$img-$x-$y"];
300 }
301
302 // valeur par defaut si l'image ne peut etre lue
303 $defaut = "F26C4E";
304
305 $cache = _image_valeurs_trans($img, "coul-$x-$y", "txt");
306 if (!$cache) {
307 return $couleur_extraite["$img-$x-$y"] = $defaut;
308 }
309
310
311 $fichier = $cache["fichier"];
312 $dest = $cache["fichier_dest"];
313
314 if (isset($couleur_extraite["$fichier-$x-$y"])) {
315 return $couleur_extraite["$fichier-$x-$y"];
316 }
317
318 $creer = $cache["creer"];
319
320 if ($creer) {
321 if (@file_exists($fichier)) {
322 $width = $cache["largeur"];
323 $height = $cache["hauteur"];
324
325 $newwidth = 20;
326 $newheight = 20;
327
328 $thumb = imagecreate($newwidth, $newheight);
329
330 $source = $cache["fonction_imagecreatefrom"]($fichier);
331
332 imagepalettetotruecolor($source);
333
334 imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
335
336 do {
337 // get a color
338 $color_index = imagecolorat($thumb, $x, $y);
339
340 // make it human readable
341 $color_tran = imagecolorsforindex($thumb, $color_index);
342 $x++;
343 $y++;
344 } while ($color_tran['alpha'] == 127 and $x < $newwidth and $y < $newheight);
345
346 $couleur = _couleur_dec_to_hex($color_tran["red"], $color_tran["green"], $color_tran["blue"]);
347 } else {
348 $couleur = $defaut;
349 }
350
351 // Mettre en cache le resultat
352 $couleur_extraite["$fichier-$x-$y"] = $couleur;
353 ecrire_fichier($dest, $couleur_extraite["$fichier-$x-$y"]);
354 } else {
355 lire_fichier($dest, $couleur_extraite["$fichier-$x-$y"]);
356 }
357
358 return $couleur_extraite["$img-$x-$y"] = $couleur_extraite["$fichier-$x-$y"];
359 }
360
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) {
368 $vx = $xo - $x0;
369 $vy = $yo - $y0;
370 $d = 1 - (sqrt(($vx) * ($vx) + ($vy) * ($vy)) / sqrt(2));
371
372 return $d;
373 }
374
375
376 /**
377 * Decale une composante de couleur
378 * entier de 0 a 255
379 *
380 * @param int $coul
381 * @param int $gamma
382 * @return int
383 */
384 function _image_decale_composante($coul, $gamma) {
385 $coul = $coul + $gamma;
386
387 if ($coul > 255) {
388 $coul = 255;
389 }
390 if ($coul < 0) {
391 $coul = 0;
392 }
393
394 return $coul;
395 }
396
397 /**
398 * Decalage d'une composante de couleur en sepia
399 * entier de 0 a 255
400 *
401 * @param int $coul
402 * @param int $val
403 * @return int
404 */
405 function _image_decale_composante_127($coul, $val) {
406 if ($coul < 127) {
407 $y = round((($coul - 127) / 127) * $val) + $val;
408 } else {
409 if ($coul >= 127) {
410 $y = round((($coul - 127) / 128) * (255 - $val)) + $val;
411 } else {
412 $y = $coul;
413 }
414 }
415
416 if ($y < 0) {
417 $y = 0;
418 }
419 if ($y > 255) {
420 $y = 255;
421 }
422
423 return $y;
424 }