如何在SQL中找到最接近的颜色?

如何在SQL中找到最接近的颜色?,sql,sql-server,tsql,sql-server-2016,Sql,Sql Server,Tsql,Sql Server 2016,我有一个带有递增颜色编号的表,以及相应的HTML十六进制值。(不带#的十六进制值) 现在我有了颜色 e、 g.'007FFF',需要在表中找到最接近的颜色(T_SYS_ColorToHex) 我该怎么做 为了定义差异,您需要首先定义一个度量 因为它是RGB,它在3d空间中,所以你可以简单地使用欧几里德范数/距离 sqrt((r1-r2)2+(g1-g2)2+(b1-b2)2) 您需要提取每个组件(R、G、B)并将其转换为数字 ,CONVERT(int, CONVERT(varbinary, SU

我有一个带有递增颜色编号的表,以及相应的HTML十六进制值。(不带#的十六进制值)

现在我有了颜色

e、 g.
'007FFF'
,需要在表中找到最接近的颜色(T_SYS_ColorToHex)


我该怎么做

为了定义差异,您需要首先定义一个度量
因为它是RGB,它在3d空间中,所以你可以简单地使用欧几里德范数/距离

sqrt((r1-r2)2+(g1-g2)2+(b1-b2)2)

您需要提取每个组件(R、G、B)并将其转换为数字

,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 1, 2), 2)) AS R
,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 3, 2), 2)) AS G
,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 5, 2), 2)) AS B
此外,您只是在进行比较,因此不需要有效值,只需要相对值。所以你可以跳过计算平方根

然后,在按距离升序排序时,只需获得第一个元组

这意味着,像这样:

SELECT 
     COL_Number 
    ,COL_Hex 

    ,R2
    ,G2 
    ,B2 

    ,R1
    ,G1 
    ,B1 

    -- Comparisons are relative - SQRT not necessary 
    ,--SQRT( 
        POWER((r1 - r2), 2) + POWER((g1 - g2), 2) + POWER((b1 - b2), 2) 
    --) 
    AS dist 
FROM 
(
    SELECT 
         COL_Number
        ,COL_Hex
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 1, 2), 2)) AS R2
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 3, 2), 2)) AS G2
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 5, 2), 2)) AS B2


        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(ColorToEvaluate, 1, 2), 2)) AS R1 
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(ColorToEvaluate, 3, 2), 2)) AS G1 
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(ColorToEvaluate, 5, 2), 2)) AS B1 
    FROM T_SYS_ColorToHex 

    CROSS JOIN 
    (
        SELECT 'FF00FF' AS ColorToEvaluate 
    ) AS tParam 

) AS t  

ORDER BY dist 

OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY 

为了定义差异,您需要首先定义一个度量
因为它是RGB,它在3d空间中,所以你可以简单地使用欧几里德范数/距离

sqrt((r1-r2)2+(g1-g2)2+(b1-b2)2)

您需要提取每个组件(R、G、B)并将其转换为数字

,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 1, 2), 2)) AS R
,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 3, 2), 2)) AS G
,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 5, 2), 2)) AS B
此外,您只是在进行比较,因此不需要有效值,只需要相对值。所以你可以跳过计算平方根

然后,在按距离升序排序时,只需获得第一个元组

这意味着,像这样:

SELECT 
     COL_Number 
    ,COL_Hex 

    ,R2
    ,G2 
    ,B2 

    ,R1
    ,G1 
    ,B1 

    -- Comparisons are relative - SQRT not necessary 
    ,--SQRT( 
        POWER((r1 - r2), 2) + POWER((g1 - g2), 2) + POWER((b1 - b2), 2) 
    --) 
    AS dist 
FROM 
(
    SELECT 
         COL_Number
        ,COL_Hex
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 1, 2), 2)) AS R2
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 3, 2), 2)) AS G2
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(COL_Hex, 5, 2), 2)) AS B2


        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(ColorToEvaluate, 1, 2), 2)) AS R1 
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(ColorToEvaluate, 3, 2), 2)) AS G1 
        ,CONVERT(int, CONVERT(varbinary, SUBSTRING(ColorToEvaluate, 5, 2), 2)) AS B1 
    FROM T_SYS_ColorToHex 

    CROSS JOIN 
    (
        SELECT 'FF00FF' AS ColorToEvaluate 
    ) AS tParam 

) AS t  

ORDER BY dist 

OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY 

为什么你有一个专门的颜色数据库,它没有所有可能的价值?哪一个最接近
017FFF
007FFE
?@SaggingRufus:是的,我们有一个使用整数和256色的第三方应用程序。@StefanSteiger-确切地说;)如果这是真的,那么每种颜色将有多达6个相等的答案(紫色可能有蓝色/红色/棕色/浅紫色/深紫色,所有颜色之间的距离相等),他将需要一些“排序”逻辑来选择一个答案,除非他同意将多达6种颜色作为“最近的”。你的答案是很好的,他唯一需要考虑的是“按DIST排序”可以有多个相等的DIST值,他需要一些逻辑来确定使用多个值中的哪一个,或者根据SQL默认命令的顺序将其随机设置。@第十二:同意,现在,他必须添加进一步的逻辑来确定最佳颜色。但我想,当从1600万种颜色转换到256种颜色时,一个任意的记录就足够了——无论如何,在这种情况下,你不可能有两种完全“同样好”的匹配颜色。为什么你有一个专门用于颜色的数据库,却没有所有可能的值?哪种最接近
017FFF
007FFE
?@SaggingRufus:是的,我们有一个使用整数和256色的第三方应用程序。@StefanSteiger-确切地说;)如果这是真的,那么每种颜色将有多达6个相等的答案(紫色可能有蓝色/红色/棕色/浅紫色/深紫色,所有颜色之间的距离相等),他将需要一些“排序”逻辑来选择一个答案,除非他同意将多达6种颜色作为“最近的”。你的答案是很好的,他唯一需要考虑的是“按DIST排序”可以有多个相等的DIST值,他需要一些逻辑来确定使用多个值中的哪一个,或者根据SQL默认命令的顺序将其随机设置。@第十二:同意,现在,他必须添加进一步的逻辑来确定最佳颜色。但我想,当从1600万种颜色转换到256种颜色时,一个任意的记录就足够了——无论如何,在这种情况下,你不可能有两种完全“同样好”的匹配颜色。