Генерация градиентов программно? - PullRequest
28 голосов
/ 26 августа 2008

Учитывая 2 цвета RGB и прямоугольную область, я хотел бы создать базовый линейный градиент между цветами. Я сделал быстрый поиск, и единственное, что мне удалось найти, это эта запись в блоге , но пример кода отсутствует или, по крайней мере, был на момент публикации. Все помогает, алгоритмы, примеры кода, что угодно. Это будет написано на Java, но об уровне отображения уже позаботились, мне просто нужно выяснить, как выяснить, что отображать.

Ответы [ 5 ]

38 голосов
/ 26 августа 2008

вы хотите интерполяцию между первым и вторым цветом. Интерполировать цвета легко, рассчитав одинаковую интерполяцию для каждого из его компонентов (R, G, B). Есть много способов интерполировать. Проще всего использовать линейную интерполяцию: достаточно взять процент p первого цвета и процент 1 - p второго:

R = firstCol.R * p + secondCol.R * (1 - p)

Есть другой вопрос , связанный с этим.

Существуют и другие методы интерполяции, которые иногда работают лучше. Например, использование интерполяционной функции в форме колокола *1013* делает переход более плавным.

/ EDIT: К сожалению, вы имеете в виду использование предопределенной функции. ОК, еще проще. Сообщение в блоге, на которое вы ссылаетесь, теперь имеет пример кода на Python.

В Java вы можете использовать GradientPaint.

10 голосов
/ 26 августа 2008

Вы можете использовать встроенный класс GradientPaint .

void Paint(Graphics2D g, Regtangle r, Color c1, Color c2)
{
  GradientPaint gp = new GradientPaint(0,0,c1,r.getWidth(),r.getHeight(),c2); 
  g.setPaint(gp);
  g.fill(rect);
}
9 голосов
/ 26 августа 2008

Используя базовые классы AWT, вы можете сделать что-то вроде этого:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;

public class LinearGradient extends JPanel {

    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        Color color1 = Color.RED;
        Color color2 = Color.BLUE;
        int steps = 30;
        int rectWidth = 10;
        int rectHeight = 10;

        for (int i = 0; i < steps; i++) {
            float ratio = (float) i / (float) steps;
            int red = (int) (color2.getRed() * ratio + color1.getRed() * (1 - ratio));
            int green = (int) (color2.getGreen() * ratio + color1.getGreen() * (1 - ratio));
            int blue = (int) (color2.getBlue() * ratio + color1.getBlue() * (1 - ratio));
            Color stepColor = new Color(red, green, blue);
            Rectangle2D rect2D = new Rectangle2D.Float(rectWidth * i, 0, rectWidth, rectHeight);
            g2.setPaint(stepColor);
            g2.fill(rect2D);
        }
    }
}
2 голосов
/ 16 ноября 2017

В ответ на отличный ответ Дэвида Кроу, вот пример реализации Kotlin

fun gradientColor(x: Double, minX: Double, maxX: Double, 
                  from: Color = Color.RED, to: Color = Color.GREEN): Color {
    val range = maxX - minX
    val p = (x - minX) / range

   return Color(
        from.red * p + to.red * (1 - p),
        from.green * p + to.green * (1 - p),
        from.blue * p + to.blue * (1 - p),
        1.0
    )
}
0 голосов
/ 21 октября 2008

Я использовал RMagick для этого . Если вам нужно пойти дальше, простой градиент может быть полезен ImageMagick и одна из его оболочек (например, RMagick или JMagick для Java).

...