Oggi propongo una piccola soluzione in SQL al problema dell’ordinamento dei colori. Una cosa apparentemente elementare si rivela in realtà estremamente complessa. Per un approfondimento generale sul tema consiglio questo interessantissimo articolo: The incredibly challenging task of sorting colours
Per quello che mi interessa voglio proporre oggi la soluzione dell’utilizzo dello spazio HSV per poterli ordinare.
Supponiamo di avere un database di colori in RGB formato esadecimale del CSS (per intendersi il rosso sarebbe #ff0000). Nell’esempio riportato suppongo che il codice di colore sia sempre a 6 caratteri.
Detto tutto questo andiamo alla nostra funzione in SQL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
CREATE FUNCTION `RGB_TO_INT`(`colore` VARCHAR(100), parametro VARCHAR(1)) RETURNS INT(255) NOT DETERMINISTIC NO SQL SQL SECURITY DEFINER BEGIN DECLARE intero INT(255); DECLARE r INT(255); DECLARE g INT(255); DECLARE b INT(255); DECLARE maxrgb INT(255); DECLARE minrgb INT(255); DECLARE v INT(255); DECLARE h INT(255); DECLARE s INT(255); SET intero = 0; SET r = CONVERT(CONV(SUBSTRING(colore,2,2), 16,10),UNSIGNED INTEGER); SET g = CONVERT(CONV(SUBSTRING(colore,4,2), 16,10),UNSIGNED INTEGER); SET b = CONVERT(CONV(SUBSTRING(colore,6,2), 16,10),UNSIGNED INTEGER); SET v = 0; SET h = 0; SET s = 0; SELECT GREATEST(r, g, b) INTO maxrgb; SELECT LEAST(r, g, b) INTO minrgb; SET v = maxrgb; IF v = 0 THEN SET h = 0; SET s = 0; ELSE SET s = ROUND(255 * (maxrgb-minrgb) / v); IF s = 0 THEN SET h = 0; ELSE IF maxrgb = r THEN SET h = ROUND( 43 * ( g - b ) / (maxrgb-minrgb) ); ELSEIF maxrgb = g THEN SET h = ROUND( 85 + 43 * ( b - r ) / (maxrgb-minrgb) ); ELSE SET h = ROUND( 171 + 43 * ( r - g ) / (maxrgb-minrgb) ); END IF; END IF; END IF; IF parametro = 'H' THEN SET intero = h; ELSEIF parametro = 'S' THEN SET intero = s; ELSE SET intero = v; END IF; RETURN intero; END |
Per utilizzarla possiamo fare così:
1 2 3 4 5 6 7 8 |
SELECT * FROM tabella_colori tc ORDER BY RGB_TO_INT(tc.rgb_hex,'V'), RGB_TO_INT(tc.rgb_hex,'H'), RGB_TO_INT(tc.rgb_hex,'S') |