在MYSQL db中将rgb值迁移到HSL和hex

时间:2012-09-13 15:34:26

标签: mysql colors rgb

我有一个看起来像这样的mysql数据库

target_color       
'rgb(200,200,200)'
'rgb(190,29,209)'

我需要生成一个看起来像这样的数据库

target_hue   ~   target_saturation  ~ target_lightness   ~   hex_value
10          ~    40        ~         40           ~         a567ff

我遇到的主要问题是解析rgb(x,y,z)以提取值。我认为正则表达式可以解决这个问题,但是它们在mysql中不受支持...尝试substrint()substring_index(),但是完全纠缠不清......

3 个答案:

答案 0 :(得分:1)

您可以使用SUBSTRING_INDEX函数提取逗号之间的各个整数值。

SET @rgb := 'rgb(190,29,209)' ;

SELECT @rgb
     , @rgbv := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgb,'rgb(',-1),')',1) AS `@rgbv`
     , @v1 := SUBSTRING_INDEX(@rgbv,',',1)                             AS `@v1`
     , @v2 := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgbv,',',2),',',-1)     AS `@v2`
     , @v3 := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgbv,',',3),',',-1)     AS `@v3`
     , 0 + @v1  AS R
     , 0 + @v2  AS G
     , 0 + @v3  AS B

SELECT列表中的最后三列表明用户变量可以用在其他(后续)表达式中,在这种情况下,将它们添加到整数值0以将它们作为整数返回。

不幸的是,MySQL不提供GREATESTLEAST功能。那些方便,所以你可以用这样的表达式获得Hue的值:

GREATEST(0+@v1,0+@v2,0+@v3) - LEAST(0+@v1,0+@v2,0+@v3)

你可以为这三个值“推出自己的”最大和最小函数:

IF(0+@v1>0+@v2
  ,IF(0+@v1>0+@v3,0+@v1,IF(0+@v2>0+@v3,0+@v2,0+@v3))
  ,IF(0+@v2>0+@v3,0+@v2,0+@v3)
  ) AS `max(R,G,B)`

IF(0+@v1<0+@v2
  ,IF(0+@v1<0+@v3,0+@v1,IF(0+@v2<0+@v3,0+@v2,0+@v3))
  ,IF(0+@v2<0+@v3,0+@v2,0+@v3)
  ) AS `min(R,G,B)`

从包含名为rgb的列的表中,查询可能如下所示:

SELECT s.R
     , s.G
     , s.B
     , IF(s.R>s.G,IF(s.R>s.B,s.R,s.B),IF(s.G>s.B,s.G,s.B)) AS `max(R,G,B)`
     , IF(s.R<s.G,IF(s.R<s.B,s.R,s.B),IF(s.G<s.B,s.G,s.B)) AS `min(R,G,B)`
  FROM (
         SELECT t.rgb
              , @rgbv := SUBSTRING_INDEX(SUBSTRING_INDEX(t.rgb,'rgb(',-1),')',1) AS `@rgbv`
              , @v1 := SUBSTRING_INDEX(@rgbv,',',1)                              AS `@v1`
              , @v2 := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgbv,',',2),',',-1)      AS `@v2`
              , @v3 := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgbv,',',3),',',-1)      AS `@v3`
              , 0 + @v1  AS v1
              , 0 + @v2  AS v2
              , 0 + @v3  AS v3
           FROM mytable t
       ) s

答案 1 :(得分:0)

鉴于包含'rgb(190,29,209)'的字段名为rgb,您可以使用此sql提取这三个值:

select 
   substring(rgb, locate('(',rgb)+1,locate(',',rgb) -1 - locate('(',rgb)) as red,
   substring(substring_index(rgb,',',2) , locate(',',rgb)+1) as green,
   substring(rgb, locate(',',rgb, locate(',',rgb)+1 )+1 , locate(')',rgb) 
                   -1 - locate(',',rgb, locate(',',rgb)+1 )) as blue

将输出此结果集:

red  green  blue
190  29     209

答案 2 :(得分:0)

我用它将csv rgb值直接转换为十六进制。

UPDATE table1 ami
JOIN 
(
SELECT id, value 
, SUBSTRING(value, 1, LOCATE(',', value)-1) as R
, SUBSTRING(value, LOCATE(',', value)+1, LOCATE(',', value, LOCATE(',', value)+1) - LOCATE(',', value) - 1) G
, SUBSTRING(value, LOCATE(',', value, LOCATE(',', value)+1)+1) B
from table1 ai
where locate(',', value) > 0
) tbl ON ami.id = tbl.id
SET ami.value = CONCAT(
 LPAD(CONV(tbl.R, 10, 16),2,'0') 
, LPAD(CONV(tbl.G, 10, 16),2,'0')
, LPAD(CONV(tbl.B, 10, 16),2,'0'));

显然更改表名:) 希望这有助于其他人。