Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
User interface 通过编程使颜色变亮_User Interface_Language Agnostic_Colors - Fatal编程技术网

User interface 通过编程使颜色变亮

User interface 通过编程使颜色变亮,user-interface,language-agnostic,colors,User Interface,Language Agnostic,Colors,动机 我想找到一种方法,以采取任意颜色,并减轻了一些阴影,这样我就可以编程创建一个很好的梯度从一种颜色到一个更轻的版本。渐变将用作UI中的背景 可能性1 很明显,我可以把RGB值分开,单独增加一定量。这真的是我想要的吗 可能性2 我的第二个想法是将RGB转换为HSV/HSB/HSL(色调、饱和度、值/亮度/亮度),增加亮度一点,减少饱和度一点,然后将其转换回RGB。一般来说,这会有理想的效果吗?我会选择第二个选项。一般来说,RGB空间并不适合进行颜色处理(创建从一种颜色到另一种颜色的过渡、使颜色

动机

我想找到一种方法,以采取任意颜色,并减轻了一些阴影,这样我就可以编程创建一个很好的梯度从一种颜色到一个更轻的版本。渐变将用作UI中的背景

可能性1

很明显,我可以把RGB值分开,单独增加一定量。这真的是我想要的吗

可能性2


我的第二个想法是将RGB转换为HSV/HSB/HSL(色调、饱和度、值/亮度/亮度),增加亮度一点,减少饱和度一点,然后将其转换回RGB。一般来说,这会有理想的效果吗?

我会选择第二个选项。一般来说,RGB空间并不适合进行颜色处理(创建从一种颜色到另一种颜色的过渡、使颜色变亮/变暗等)。下面是我通过快速搜索找到的两个站点,它们可以从RGB转换为HSL或从HSL转换为RGB:

  • -应易于适应其他编程语言

我会先试试数字1,但数字2听起来不错。试着自己做,看看你对结果是否满意,听起来你可能需要10分钟来准备一个测试。

之前有人问过一个非常类似的问题,并给出了有用的答案:

简短回答:如果您只需要“足够好”,请将RGB值乘以常数,如果您需要精度,请转换为HSV。

在C#中:


我到处都在使用它。

转换为HS(LVB),增加亮度,然后转换回RGB是可靠地使颜色变亮而不影响色调和饱和度值的唯一方法(即仅使颜色变亮而不以任何其他方式改变颜色).

将其转换为RGB,并在原始颜色和目标颜色(通常为白色)之间进行线性插值。因此,如果您希望两种颜色之间有16种色调,您可以:


for(i = 0; i < 16; i++)
{
  colors[i].R = start.R + (i * (end.R - start.R)) / 15;
  colors[i].G = start.G + (i * (end.G - start.G)) / 15;
  colors[i].B = start.B + (i * (end.B - start.B)) / 15;
}

对于(i=0;i<16;i++)
{
颜色[i].R=start.R+(i*(end.R-start.R))/15;
颜色[i].G=start.G+(i*(end.G-start.G))/15;
颜色[i].B=start.B+(i*(end.B-start.B))/15;
}
我用两种方法都做到了——使用可能性2可以获得更好的结果

为可能性1构造的任何简单算法可能仅在有限的起始饱和范围内有效

如果(1)可以限制使用的颜色和亮度,以及(2)在渲染中大量执行计算,则需要查看Poss 1

为UI生成背景不需要太多着色计算,因此我建议使用Poss 2


-Al.

从技术上讲,我认为两者都不正确,但我相信您需要选项2的变体。问题是,使用RGB 990000并“点亮”它实际上只会增加红色通道(值、亮度、亮度),直到到达FF。在那之后(纯红),它会降低饱和度,一直到纯白

转换变得很烦人,特别是因为你不能直接进出RGB和Lab,但我认为你真的想分离色度和亮度值,只需修改亮度就可以真正达到你想要的效果。

因为你想通过乘法使物体更亮,但这只在其中一种颜色饱和(即达到255或更高)之前有效。在这一点上,您可以将值钳制为255,但当您变亮时,您将微妙地更改色调。要保持色调,您需要保持(中间-最低)/(最高-最低)的比率

这里有两个Python函数。第一种实现了简单的方法,如果RGB值超过这个值,它只会将RGB值钳制到255。第二种方法重新分配多余的值以保持色调不变

def clamp_rgb(r, g, b):
    return min(255, int(r)), min(255, int(g)), min(255, int(b))

def redistribute_rgb(r, g, b):
    threshold = 255.999
    m = max(r, g, b)
    if m <= threshold:
        return int(r), int(g), int(b)
    total = r + g + b
    if total >= 3 * threshold:
        return int(threshold), int(threshold), int(threshold)
    x = (3 * threshold - total) / (3 * m - total)
    gray = threshold - x * m
    return int(gray + x * r), int(gray + x * g), int(gray + x * b)
def夹持器rgb(r、g、b): 返回min(255,int(r)),min(255,int(g)),min(255,int(b)) def重新分配\u rgb(r、g、b): 阈值=255.999 m=最大值(r、g、b) 如果m=3*阈值: 返回int(阈值)、int(阈值)、int(阈值) x=(3*阈值-总计)/(3*m-总计) 灰色=阈值-x*m 返回整数(灰色+x*r)、整数(灰色+x*g)、整数(灰色+x*b) 我创建了一个渐变,从RGB值(224128,0)开始,然后将它乘以1.0、1.1、1.2等,直到2.0。上半部分是使用
clamp_rgb
的结果,下半部分是使用
redistribute_rgb
的结果。我认为很容易看出,重新分配溢出会得到更好的结果,而不必离开RGB颜色空间

为了进行比较,这里是由Python模块实现的HLS和HSV颜色空间中的相同渐变。仅修改了
L
组件,并对生成的RGB值执行夹紧。结果类似,但需要对每个像素进行颜色空间转换


您将在System.Windows.Forms命名空间中的

ControlPaint类中找到在颜色空间之间转换的代码,该类具有静态方法Light和Dark:

public static Color Dark(Color baseColor, float percOfDarkDark);
这些方法使用HLSColor的私有实现。我希望这个结构是公共的,并且在System.Drawing中


或者,您可以使用颜色结构上的GetHue、GetSaturation、GetBrightness来获取HSB组件。不幸的是,我没有找到反向转换。

如果您想产生渐变淡出,我建议进行以下优化:与其对每个颜色执行RGB->HSB->RGB,不如只计算目标颜色。一旦知道目标RGB,就可以简单地计算RGB空间中的中间值,而无需来回转换。是否使用某种曲线计算线性过渡取决于您。

我有一个演示如何在Delphi中执行此操作的示例。它非常简单,因为函数ColorRGBToHSL和ColorHLSToRGB是标准库的一部分。

public static Color Dark(Color baseColor, float percOfDarkDark);
float correctionFactor = 0.5f;
float red = (255 - color.R) * correctionFactor + color.R;
float green = (255 - color.G) * correctionFactor + color.G;
float blue = (255 - color.B) * correctionFactor + color.B;
Color lighterColor = Color.FromArgb(color.A, (int)red, (int)green, (int)blue);
function calcLightness(l, r, g, b) {
    var tmp_r = r;
    var tmp_g = g;
    var tmp_b = b;

    tmp_r = (255 - r) * l + r;
    tmp_g = (255 - g) * l + g;
    tmp_b = (255 - b) * l + b;

    if (tmp_r > 255 || tmp_g > 255 || tmp_b > 255) 
        return { r: r, g: g, b: b };
    else 
        return { r:parseInt(tmp_r), g:parseInt(tmp_g), b:parseInt(tmp_b) }
}
oneMinus = 1.0 - amount
r = amount + oneMinus * r
g = amount + oneMinus * g
b = amount + oneMinus * b
oneMinus = 1.0 - amount
r = amount * dest_r + oneMinus * r
g = amount * dest_g + oneMinus * g
b = amount * dest_b + oneMinus * b
def lighten(hex, amount):
    """ Lighten an RGB color by an amount (between 0 and 1),

    e.g. lighten('#4290e5', .5) = #C1FFFF
    """
    hex = hex.replace('#','')
    red = min(255, int(hex[0:2], 16) + 255 * amount)
    green = min(255, int(hex[2:4], 16) + 255 * amount)
    blue = min(255, int(hex[4:6], 16) + 255 * amount)
    return "#%X%X%X" % (int(red), int(green), int(blue))
tinycolor("red").lighten().desaturate().toHexString() // "#f53d3d"