Java 平滑颜色过渡



假设我有两种颜色。

public final static Color FAR = new Color(237, 237, 30);
public final static Color CLOSE = new Color(58, 237, 221);

如何在不浸入深色的情况下从一种颜色过渡到另一种颜色?

我想出了这样的想法:

    double ratio = diff / range; // goes from 1 to 0
    int red = (int)Math.abs((ratio * FAR.getRed()) - ((1 - ratio) * CLOSE.getRed()));
    int green = (int)Math.abs((ratio * FAR.getGreen()) - ((1 - ratio) * CLOSE.getGreen()));
    int blue = (int)Math.abs((ratio * FAR.getBlue()) - ((1 - ratio) * CLOSE.getBlue()));

    double ratio = diff / range; // goes from 1 to 0
    int red = (int) ((1 - (diff / range)) * FAR.getRed() + CLOSE.getRed() - FAR.getRed());
    int green = (int) ((1 - (diff / range)) * FAR.getGreen() + CLOSE.getGreen() - FAR.getGreen());
    int blue = (int) ((1 - (diff / range)) * FAR.getBlue() + CLOSE.getBlue() - FAR.getBlue());

但不幸的是,它们都没有从一种颜色平稳过渡到另一种颜色。有谁知道如何在保持颜色明亮而不浸入较暗颜色的同时做到这一点,或者如何确保渐变过渡平滑而不是先慢然后快然后又慢?

我真的不能想出任何公式。

您在计算中使用了错误的符号。应该是加号,而不是减号,以正确应用比率。

int red = (int)Math.abs((ratio * FAR.getRed()) + ((1 - ratio) * CLOSE.getRed()));
int green = (int)Math.abs((ratio * FAR.getGreen()) + ((1 - ratio) * CLOSE.getGreen()));
int blue = (int)Math.abs((ratio * FAR.getBlue()) + ((1 - ratio) * CLOSE.getBlue()));

使用现有实现获得深色的原因是,对于 (-),它们通常会接近于零(小于 50?或负数但大于 -50?),而在负数情况下,好吧,您采用绝对值,因此它变成了一个小的正数,即深色。

(ratio * FAR.getGreen()) + ((1 - ratio) * CLOSE.getGreen())
如果比率从 0 到 1,那么这是加权平均值,假设比率 = 1/2,那么

它将是 Aritical 平均值,如果比率 = 1/3,那么它是加权平均值,其中 FAR 的权重为 1,CLOSE 的权重为 2

这对我来说效果很好:

// Steps between fading from one colour to another.
private static final int FadeSteps = 25;
private void fade(Label panel, Color colour) throws InterruptedException {
  final Color oldColour = panel.getBackground();
  final int dRed = colour.getRed() - oldColour.getRed();
  final int dGreen = colour.getGreen() - oldColour.getGreen();
  final int dBlue = colour.getBlue() - oldColour.getBlue();
  // No point if no difference.
  if (dRed != 0 || dGreen != 0 || dBlue != 0) {
    // Do it in n steps.
    for (int i = 0; i <= FadeSteps; i++) {
      final Color c = new Color(
              oldColour.getRed() + ((dRed * i) / FadeSteps),
              oldColour.getGreen() + ((dGreen * i) / FadeSteps),
              oldColour.getBlue() + ((dBlue * i) / FadeSteps));
      panel.setBackground(c);
      Thread.sleep(10);
    }
  }
}

不是最整洁的代码,但它有效。

最新更新