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


9

我有这张照片:

颜色

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

我对我制作的应用程序进行了截屏,边缘上的褐色只是蓝色加上30。颜色。

实际颜色

如何仅给定颜色阴影,即使其更亮或更暗?

另外,如果我希望它与Alpha一起显示为半透明怎么办?


我投票关闭这个问题作为离题,因为它应该在stackoverflow上提出。
joojaa

3
从技术上讲,这仍然是一个图形设计问题,因为我们讨论颜色和底纹颜色背后的数学运算,从而产生不同的颜色变体。
弗拉德

1
不,我们讨论十六进制转换。我对颜色问题没问题,但是您已经将其与计算环境紧密地联系在一起,以致于不再满足您的要求。因此,您已经将其指定为一个JavaScript和标记节点问题,而不是图形设计。
joojaa

1
没有问题说对了,我应该怎么做才能使颜色更深或更亮。转换为十六进制值是有用的加法,但不是必需的。
弗拉德(Flad)2016年

1
我不会争论。我不了解颜色以及颜色如何工作,我只是要求一种“方法”,而不是有人会为我编写的代码。
弗拉德

Answers:


12

很酷的问题。

要使用十六进制值,您需要考虑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。


偏离路线,如果这是一个浏览器,则它完全有能力为您计算该值
joojaa '16

是的JS /浏览器应用程序。但是Js无法识别#345464格式的颜色。我使用parseInt(hashString.replace('#',``),16); 其中hashString是CSS格式的颜色,例如#345464。
弗拉德

您可以随意翻译号码。我说的是使用数字,以便您可以查看其背后的数学。但是原理是一样的。图8是F的一半
圣拉斐尔

而且,您始终可以使用rgba(255,128,0,1)表示法。
拉斐尔

实际上,我使用的是Canvas元素,它是纯JS,不包含CSS。但是我对如何用代码解决这个问题有了一个想法。
弗拉德(Flad)2016年

2

您有点误解了,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上找到。


该库可以独立吗?
弗拉德

@弗拉德确定我没有理由不这样做。
joojaa

我尝试过,它使用了一些NodeJS模块,但是我不想使应用程序过于依赖第三方库。会尝试制作自己的代码。
弗拉德

@Vlad在头皮上为您添加了一些代码
joojaa's

:D哇,出色的工作!
弗拉德

1

如果要手动更改颜色的暗度/亮度,甚至不看它,则手动进行。以十六进制或RGB为单位的操作非常简单, 只需向每个通道添加或减去相等数量的光即可。
在rgb中说,您有132,145,167,您可以将每个数字加30以获得相同颜色的较浅版本,因此为162,175,207,如果您意识到自己做了一点,然后从每个数字中减去2,则为160,173,205。与十六进制相同,但十六进制数字相同。因此e4c3d5是e4 c3 d5,您可以加16使其变浅f4d3e5,或者减去16则使相同颜色d4b3c5变暗。
您可以根据需要添加或减去任意数量,并且您会更好地猜测加班和减去加班的正确数量,只要您将相同数量的数量添加到所有三个通道(所有三个数字)中,您只会更改您从混合物中添加或去除了多少白色。


凉!对于非编码人员来说,这是如此简单和有用!
brookdancer
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.