Algoritmo para gerar um spectro de cores

6 respostas
Mikhas

hey Galerinha /o/

Eu acho JColorChooser do java um componente muito desajeitado… então estou fazendo o meu proprio componente.

O unico problema é que eu não sei o algoritmo para gerar o spectro de cores.
Até consegui fazer um spetro circular, mas ele parece não estar com tantas cores quanto eu queria.

Quero fazer um igual o do paint do windows, o quadrado.

Alguem tem idea de como é o algoritmo?
Ja procurei no google e nada :cry:

6 Respostas

victorwss

java.awt.Color.HSBtoRGB(float, float, float)
java.awt.Color.RGBtoHSB(int, int, int, float[])

Mikhas

Porra…

Não custa nada dar uma breve explicação do que diabos seja isso e como posso usar a meu favor;

B

Dê uma olhada no ColorPicker em http://colorchooser.dev.java.net/

Mikhas

Valew Bruno. Era isso mesmo oque eu queria.

Mas se alguem puder me ajudar com o algoritmo, seria muito interessante :thumbup:

ViniGodoy

Para fazer o espectro igual ao do “Cores personalizadas” do paint:
A primeira cor, do canto superior direito, é 255 no vermelho, 0 no verde e 0 no azul.

Vá subindo 1 no verde no pixel da direta, até o 255.
Quando chegar no 255, comece a descer um no vermelho até chegar a 0.
Então, passe a subir 1 no canal azul, até que esse chegue a 255.
Quando chegar lá, diminua 1 do verde, até que chegue a 0.
Chegando lá, volte a subir 1 no vermelho, até que chegue a 255.
Finalmente, chegando lá, diminua 1 do azul, até chegar a 0.

Para as linhas debaixo, some um no mínimo, ou calcule proporcionalmente (eu gosto mais da última opção, apesar de não ficar idêntico ao paint).

ViniGodoy

Aqui vai um exemplo:

public class TesteEspectro extends JFrame {
    public TesteEspectro() {
        this.setSize(800, 600);
        this.setExtendedState(JFrame.MAXIMIZED_BOTH);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new BorderLayout());
        this.add(new EspectroPanel(), BorderLayout.CENTER);        
    }
    
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable()
        {
            @Override
            public void run() {
                new TesteEspectro().setVisible(true);
            }
        });
    }
}

package espectro;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;

import javax.swing.JPanel;

public class EspectroPanel extends JPanel {
    private static final int FACTOR = 5;

    private void drawPoint(Graphics2D g2d, int x, int y, int a, int b, int c) {
        double prop = (255.0 - y) / 255;

        g2d.setColor(new Color((int) (a * prop), (int) (b * prop),
                (int) (c * prop)));
        g2d.drawLine(x, y, x + FACTOR, y);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setTransform(AffineTransform.getScaleInstance(getWidth()/1530.0, getHeight()/255.0));

        for (int line = 0; line < 255; line++) {            
            for (int z = 0, x = 0; z < 255/FACTOR; z++, x=FACTOR*z) {
                // Aumenta o verde
                drawPoint(g2d, x, line, 255, x, 0);

                // Mantém o verde, diminui o vermelho
                drawPoint(g2d, x + 255, line, 255 - x, 255, 0);

                // Passa a subir o azul
                drawPoint(g2d, x + 510, line, 0, 255, x);

                // Diminui do verde
                drawPoint(g2d, x + 765, line, 0, 255 - x, 255);

                // Aumenta o vermelho
                drawPoint(g2d, x + 1020, line, x, 0, 255);

                // Diminui o azul
                drawPoint(g2d, x + 1275, line, 255, 0, 255 - x);
            }
        }

        g2d.dispose();
    }
}

Esse algoritmo não incrementa de 1 em 1, mas de FACTOR em FACTOR. Isso permite que ele atue mais rapidamente. Um fator pequeno, como 5, dificilmente será perceptível ao olho humano. Um fator grande (como 25) pode ser usado para gerar "faixas de cor", um efeito típico de desenhos animados (procure por pixel shading para mais informações).

O transform no início serve para pedir para o Java fazer a escala do tamanho do espectro (1530x255) para o tamanho do painel. Assim o espectro ocupa o painel inteiro. O ideal mesmo seria alterar o algoritmo para desenhar apenas o número de pixels na área do painel, e então calcular a posição e cor do pixel proporcionalmente. Assim, um painel pequeno passaria a consumir muito pouco processamento.

Da forma que está, sempre desenhamos 1530x255/FACTOR pixels, independente do tamanho do painel.

Criado 7 de outubro de 2008
Ultima resposta 8 de out. de 2008
Respostas 6
Participantes 4