Gerando uma série de cores entre duas cores

15

Dada uma cor inicial e uma cor final, é possível gerar algoritticamente um intervalo de cores entre elas? Por exemplo, considerando os tons claros e escuros de azul / cinza no início e no final da imagem abaixo, como posso gerar os tons intermediários?

insira a descrição da imagem aqui

Uma solução possível que estou considerando é criar um gradiente a partir das duas cores e depois provar a cor em pontos equidistantes ao longo desse gradiente. Essa é provavelmente a melhor abordagem?

Ben Packard
fonte
2
Dê uma olhada no seguinte: graphicdesign.stackexchange.com/questions/75417/… Poderia ser um ducplicado?
Rafael
Outro bom artigo sobre o tema: vis4.net/blog/posts/avoid-equidistant-hsv-colors
espinho
Isto é muito perto de ser uma duplicata de esta pergunta Stack Overflow
Dawood diz Reintegrar Monica

Respostas:

13

Isso é chamado de interpolação de cores . É o que os gradientes fazem sob o capô. Você pode fazer isso usando uma variedade de meios e métodos, e exatamente como os resultados são interpolados depende do método.

Geralmente, faço isso em projetos da Web usando JavaScript, para poder alterar dinamicamente as cores, como neste visualizador de música . Uma implementação JavaScript que possui um método muito direto de interpolação linear usando RGB, extraído do exemplo acima, é o seguinte:

Demonstração ao vivo

// Returns a single rgb color interpolation between given rgb color
// based on the factor given; via https://codepen.io/njmcode/pen/axoyD?editors=0010
function interpolateColor(color1, color2, factor) {
    if (arguments.length < 3) { 
        factor = 0.5; 
    }
    var result = color1.slice();
    for (var i = 0; i < 3; i++) {
        result[i] = Math.round(result[i] + factor * (color2[i] - color1[i]));
    }
    return result;
};
// My function to interpolate between two colors completely, returning an array
function interpolateColors(color1, color2, steps) {
    var stepFactor = 1 / (steps - 1),
        interpolatedColorArray = [];

    color1 = color1.match(/\d+/g).map(Number);
    color2 = color2.match(/\d+/g).map(Number);

    for(var i = 0; i < steps; i++) {
        interpolatedColorArray.push(interpolateColor(color1, color2, stepFactor * i));
    }

    return interpolatedColorArray;
}

Que é usado assim e retorna uma matriz das cores interpoladas:

var colorArray = interpolateColors("rgb(94, 79, 162)", "rgb(247, 148, 89)", 5);

Você também pode encontrar extensões do PhotoShop (e provavelmente de outro programa) para realizar a interpolação de cores. No entanto, convém verificar se o método de interpolação é o mesmo que você deseja, pois é possível usar qualquer função para interpolar com base.

Zach Saucier
fonte
2
Zach ... você é um nerd ... esse visualizador de música é muito legal!
Rafael
@Rafael fiz alguns outros que poderá gostar também :)
Zach Saucier
Obrigado. Color Interpolationera o que eu precisava. Eu encontrei algumas implementações do Swift aqui - stackoverflow.com/questions/22868182/uico…
Ben Packard
2
O link acima é quebrado, mas o post pode ser encontrado aqui para futuros leitores: transição UIColor com base no valor progresso
Zach Saucier
23

Dê uma olhada nesta resposta. Como tornar uma determinada cor um pouco mais escura ou mais clara?

Onde você simplesmente pega os valores separados de cada componente RGB e divide os valores.

Mas temos um problema, não há apenas uma maneira de fazer uma transição de cores.

insira a descrição da imagem aqui

A primeira abordagem fornecerá a rota mais curta (1), mas provavelmente essa rota não é o que você precisa.

Isso também é afetado pelo modelo ou lógica de cores. Por exemplo, no modelo de cores Lab *, o vermelho e o verde são cores complementares, portanto a rota curta nesse modelo passará por um cinza neutro (3).

Se você só precisa de tons de uma cor, a outra resposta é adequada.

Rafael
fonte
5
I como o gráfico mostrando os diferentes métodos de interpolação
Zach Saucier
Eu acho que isso significa que deve haver uma maneira de codificar a estratégia do caminho.
Bao Thien Ngo
10

Use uma mistura no Illustrator em RGB ou CMYK:

  • crie duas formas, cada uma com a cor inicial e final (uma cinza e uma preta neste exemplo, mas escolha o que precisar)
  • Object → Blend → Blend Optionse digite quantas Specified stepsvocê precisa no meio (20 no meu exemplo abaixo)
  • selecione seus dois objetos e escolha Object → Blend → Make. Isso irá gerar a mistura que você pode transformar em objetos individuais via Object → Expand. Então você pode ver cada objeto intermediário com seu próprio código de cores.

Misturando

Lucian
fonte
5

Esta é uma adição às outras respostas.

Ao interpolar cores no sRGB, é necessário considerar que os valores RGB não são lineares na intensidade da luz, mas lineares na intensidade da luz percebida pelo homem. Isso facilita salvar valores, mas para várias operações de cores é necessário ir para o espaço linear de cores.

A percepção humana da intensidade da luz está de acordo com uma lei de potência, portanto, com

linear = sRGB^2.2
sRGB = linear^(1/2.2)

pode ser usado para transformar entre os dois. Isso usa um valor gama de 2,2, que é o valor para sRGB. Para mais informações, consulte este artigo da Wikipedia.

Uma análise detalhada desse problema e exemplos de implementações incorretas podem ser encontradas aqui . Um deles é um gradiente de cores usando interpolação linear e sRGB.

henje
fonte
Isso é um método de interpolação valores sRGB, mas o que uma pessoa deve fazer depende do efeito que eles querem
Zach Saucier
É isso mesmo, mas a interpolação no espaço linear é o que acontece com a luz na vida real. Portanto, é o mais natural fazê-lo.
henje
11
@ZachSaucier, o número de vezes que as pessoas interpolaram ou misturaram sRGB por intenção específica é muito pequeno comparado ao número de vezes que as pessoas fizeram isso por ignorância ou preguiça (pensando que estão fazendo isso em RGB ou pensando (com razão ou não) que a diferença não é importante).
Hbbs
1

O gradiente do Photoshop (ou equivalente "Blend" em Ai) já é apresentado como uma maneira de obter uma transição linear de cores entre as cores inicial e final. Como obtemos algo não linear (um caminho de transição curvo) sem programar algum código de script?

Uma solução é modificar o caminho de transição do gradiente ajustando camadas ou modos de mesclagem ou ambos. Isso realmente produz uma transformação contínua da cor inicial para a cor final, se as camadas modificadoras tiverem uma máscara de camada que seja contínua e criar a afeição = Zero no início e no final.

Aqui está uma reviravolta bastante complexa. A camada "Alvo sozinho" possui o gradiente e a camada "Modificador" produz uma mudança contínua de cor no modo de mesclagem "Cor" Para tornar tudo mais distorcido, o modificador em si é um gradiente.

Mais torção é gerada por uma camada de ajuste "Curvas" que adiciona contraste. Ele tem a mesma máscara de camada que o modificador, mas isso não é obrigatório. Qualquer máscara está ok, se for contínua e preta no início e no final.

Existem alguns modos e misturas contínuas de mistura que causam um salto abrupto. Um deles é "Hue". Outra possibilidade de estragar o efeito é "sem alteração", uma área de cor constante visível causada pelo corte de todos os zero ou todos os 255. Não testei nem calculei o quanto, na prática, ajuda a usar o modo RGB de 48 bits / pixel. Talvez não, porque ainda temos apenas 24 bits / pixel na tela.

Transição

user287001
fonte