如何使给定的颜色更深或更浅?

平面设计 颜色 十六进制
2022-01-22 12:41:23

我有这张照片:

颜色

箭头显示了两种不同的颜色,但实际上它们应该是相同的颜色,但颜色要浅一些或深一些。

我制作了我制作的应用程序的屏幕截图,边缘的褐色只是蓝色与 30 的总和。如您所见,它并不能解决问题,即在实际颜色中添加 30 并不适用于所有人颜色。

实际颜色

我怎样才能对给定的颜色进行着色,即使其更亮或更暗?

另外,如果我希望它在 alpha 中看起来是半透明的,我该怎么办?

3个回答

很酷的问题。

要使用十六进制值,您需要考虑 RGB 值的相对比例。

我将使用数字比例,而不是字母,所以我们可以看到它背后的数学。

想象一下,你有一个橙子。

你可以有R255 G128 B0的值

如果你想要更深的颜色,你需要减少值,例如 50%

这将为您提供R128 G64 B0请注意,所有颜色都使用比例比例进行了修改。

更复杂的颜色可能是R255 G200 B100让我们将其变暗,但不如前一种情况那么多。让我们把它调暗 80%。

R255x0.8 G200x0.8 B100x0.8 = R204 G160 B80

使一种颜色更亮的想法几乎相同,但它更棘手,因为颜色将上限为 255,因此您可以考虑 255 与您的值之间的差异。

例如相同的橙色

R255 G128 B0

你不能再增加 R,你不能用相同的值增加绿色和蓝色,例如增加 100,因为你将拥有

R255 G228 B100

太黄了。

数学将是

1) 255与当前值的差值(R255 G128 B0)为:R0 G127 B255

2)让我们把橙色调淡 50%

3) Rx50% Gx50% Bx50% = R0 G64 B128

4)将其添加到您的初始值:R255+0 G128+64 B0+128 = R255 G192 B128。

我正在添加一张图片来给你一个基本的想法。RGB值与我的文字不一样,只是因为一个懒惰的工作,但你可以看到橙色的“楼梯”保留了它的内在比例。

在此处输入图像描述

已编辑

我太笨了。您还可以使用 HSL 颜色表示法:

{background-color: hsl(45, 60%, 70%);} 并修改第三种颜色为较深的颜色,第二种和第三种颜色为较浅的颜色。

您还可以使用 hsla 变体来包含 alpha。


编辑:这是关于透明度的第二部分。

恢复单色图像叠加在白色上时丢失的透明度

你有点误解了,javaScript 没有将颜色建模为十六进制,系统也没有。十六进制表示法仅适用于人类可读的文档。在您的系统内部存储三个整数值。您可以直接查询和操作它们。

但是让我们说您想要操作实际文档而不是系统内部。然后最好将您的计算推迟到为您执行此操作的某个库。您会看到浏览器可以通过多种方式表示颜色,因此您需要对各种情况进行编程,例如 ad rgb 和 hsv 输入。所以我建议你使用Color.js之类的东西,它可以为你省去很多麻烦,因为你不需要自己实现混合、变暗、变亮等。

编辑:

如果您想自己这样做,我不建议这样做。首先将十六进制表示转换为 0-1 范围内的整数或浮点数的数字三元组,这使得计算更容易。

现在,为了轻松操作颜色,将 RGB 值转换为 HSL 或 HSB,这使得亮度计算变得微不足道(维基百科有公式)。因此,只需添加或减去亮度或亮度。对于真实的灯光模拟,计算很简单,只需将灯光颜色乘以基色即可。因此,对于中性光,它很简单:

结果 = 强度*颜色

正如 Rafael 解释的那样,公式通过颜色通道重复。您可以通过执行来模拟彩色光

结果 = 强度 * LigtColor * 颜色

为此最好先转换为浮点数,也可能是线性的。这样可以在您的区域提供温暖或凉爽的光线,从而带来更自然的感觉。

Alpha 混合(颜色叠加在其他颜色之上)很简单

结果 = ColorTop * alpha + ColorBottom * (1-alpha)

最终编辑

最后,这里有一些代码可以对您的要求有所帮助。这很难看到的原因是它现在的形式有点抽象。此处提供实时代码

在此处输入图像描述

图 1:下面的代码结果另见实时版本

{
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    var Color = function(r, g, b) {
      this.r = r;
      this.g = g;
      this.b = b;
    }
    Color.prototype.asHex = function() {
      return "#" + ((1 << 24) + (this.r << 16) + (this.g << 8) + this.b).toString(16).slice(1);
    }
    Color.prototype.asRGB = function() {
      return 'rgb(' + this.r + ',' + this.g + ',' + this.b + ')';
    }
    Color.prototype.blendWith = function(col, a) {
      r = Math.round(col.r * (1 - a) + this.r * a);
      g = Math.round(col.g * (1 - a) + this.g * a);
      b = Math.round(col.b * (1 - a) + this.b * a);
      return new Color(r, g, b);
    }
    Color.prototype.Mul = function(col, a) {
      r = Math.round(col.r/255 * this.r * a);
      g = Math.round(col.g/255 * this.g * a);
      b = Math.round(col.b/255 * this.b * a);
      return new Color(r, g, b);
    }
    Color.prototype.fromHex = function(hex) {
      // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
      hex = hex.substring(1,7)
      var bigint = parseInt(hex, 16);
      this.r = (bigint >> 16) & 255;
      this.g = (bigint >> 8) & 255;
      this.b = bigint & 255;
    }

    ctx.font = "16px Arial";
    ctx.fillText("Manual Alpha Blend", 18, 20);

    var a = new Color(220, 0, 150);

    var b = new Color();
    b.fromHex('#00C864');
    
    //Alpha blend
    ctx.fillStyle = a.asHex();
    ctx.fillRect(25, 25, 100, 100);
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(a.asHex(), 30, 45);
    ctx.fillStyle = b.asRGB()
    ctx.fillRect(50, 50, 100, 100);
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(a.asHex(), 55, 145);
    var bl = a.blendWith(b, 0.3);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(50, 50, 75, 75);
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(bl.asHex(), 55, 70);
    
    // lighten 1
    
    ctx.fillStyle = '#000000';
    ctx.fillText('Neutral Light', 200, 20);
    
    var c = new Color(100, 100, 100);
    var purelight= new Color(255, 255, 255);
    
    ctx.fillStyle = c.asRGB();
    ctx.fillRect(200, 25, 100, 100);
    
    var bl = c.Mul(purelight,1.2);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(225, 50, 100, 100);
    
    var bl = c.Mul(purelight, 0.8);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(250, 75, 100, 100);
    
     // lighten 2
    
    ctx.fillStyle = '#000000';
    ctx.fillText('Yellowish Light', 400, 20);
    
    var c = new Color(100, 100, 100);
    var yellowlight= new Color(255, 255, 220);
    
    var bl = c.Mul(yellowlight,1.0);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(400, 25, 100, 100);
    
    var bl = c.Mul(yellowlight,1.2);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(425, 50, 100, 100);
    
    var bl = c.Mul(yellowlight, 0.8);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(450, 75, 100, 100);
  }
}

PS您应该在stackoverflow上询问,因为实际上大部分内容都可以在stackoverfow上找到。

如果您想手动更改颜色的暗/亮,甚至不看它,请手动更改。在 hex 或 rgb 中非常容易 ,只需向每个通道添加或减去等量的光。
说在 rgb 中,你有 132,145,167,你可以在每个数字上加上 30,以获得相同颜色的更浅版本,因此 162,175,207,如果你意识到你只是稍微做了一点,然后从每个数字中减去 2,所以 160,173,205。与十六进制相同,但在十六进制数字中。所以 e4c3d5 是 e4 c3 d5 你可以添加 16 使其更亮 f4d3e5 或减去 16 使相同颜色的 d4b3c5 更暗版本。
您可以随心所欲地添加或减去,并且您会更好地猜测正确的加减加时数量,只要您将相同的数量添加到所有三个通道(所有三个数字),您只会更改方式你在混合物中添加或去除了很多白色。