【问题标题】:Java Smooth Color TransitionJava 平滑颜色过渡
【发布时间】:2013-11-19 10:12:21
【问题描述】:

假设我有两种颜色。

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());

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

我真的想不出任何公式。

【问题讨论】:

  • diffrange 是否都是整数?如果是,请注意整数除法。
  • 我在一个循环中使用它们,在这里我从 30 开始差异并下降到 0。我的范围是 30 双倍。因此,我将其用作以 30 步从 1 到 0 平稳过渡的手段。但是我认为步骤数应该没有那么重要。
  • 将 RGB 颜色空间视为cube。在立方体上找到两种颜色,然后决定如何从一个点移动到另一个点以获得所需的过渡颜色。例如,您可以在立方体中钻出一条隧道,直接从一种颜色变为另一种颜色。或者,您可以限制移动以沿着立方体的表面停留,以避免不饱和的灰色颜色。

标签: java algorithm colors


【解决方案1】:

您在计算中使用了错误的符号。应该是正数,而不是负数,才能正确应用比率。

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?),在负数情况下,嗯,你取的是绝对值,所以它变成了一个小的正数,即深色。

【讨论】:

  • 感谢工作就像一个魅力 :) 这是一个很难解决的问题,你为我节省了很多时间阅读颜色
  • 很高兴为您提供帮助。如果您要多次执行此任务,那么编写一个辅助函数非常值得。比如,int interpolate(double ratio, int value1, int value2) 返回(int)Math.abs((ratio * value1) + ((1 - ratio) * value2))。这样一来,在转换颜色时,您想要做什么总是很清楚。
  • 这是我为了好玩而搞砸的东西,所以我不想费心编写辅助函数。但是我正在做更多我想学习的颜色技巧,所以我想我稍后会发布更多问题。
【解决方案2】:
(ratio * FAR.getGreen()) + ((1 - ratio) * CLOSE.getGreen())

如果比率从 0 变为 1,那么这是加权平均,假设比率 = 1/2,那么它将是算术平均,如果比率 = 1/3,那么它是加权平均,其中 FAR 的权重为 1,并且CLOSE 的权重为 2

【讨论】:

  • 是的,我确实使用加权平均值,因为如果比率为 0,我希望颜色为 CLOSE,如果比率为 1,那么我希望颜色为 FAR,但我希望中间平滑明亮。跨度>
【解决方案3】:

这对我很有效:

// 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);
    }
  }
}

不是最简洁的代码,但它可以工作。

【讨论】:

    猜你喜欢
    • 2014-02-11
    • 2022-12-25
    • 2014-03-17
    • 1970-01-01
    • 2021-01-30
    • 2020-11-29
    • 2014-03-17
    • 1970-01-01
    • 2013-11-15
    相关资源
    最近更新 更多