【问题标题】:Generate gradient using only one color仅使用一种颜色生成渐变
【发布时间】:2012-11-28 22:26:59
【问题描述】:

我有一种颜色,例如0xFF0000。我想只使用这种颜色作为起点信息来创建简单的渐变。第二个点将是第一个颜色较浅的颜色。

例如,如果我有价值 - 0xFF0000 并且我想从中获得 0xCC0000。然后我就可以画简单的渐变了。

所以第二种颜色应该比第一种颜色浅 10% 或 20%

硬编码值是不可接受的。用户将从色轮中选择颜色,应用程序应自动生成第二种颜色以绘制简单的渐变。

有什么算法或方法可以实现吗? 可能算法会计算更高的值:R 或 G 或 B,然后并行减少其他组件,或其他东西......我不确定这是如何工作的。

P.S.:我使用的是安卓 SDK

【问题讨论】:

  • 为了获得更好的帮助,请尽快发布SSCCE,简短,可运行,可编译,只是渐变
  • 基本上,您想要的是起始颜色和...白色之间的渐变??
  • 不,只有两种颜色:红色/蓝色/绿色/橙色/紫色/其他和浅红色/浅蓝色/浅绿色/浅橙色/浅紫色/浅色其他
  • 我为另一个问题写的answer 解释了 RGB 和 HSV 颜色空间如何相互关联。这可能会有所帮助。

标签: java android colors rgb


【解决方案1】:

我认为最好的方法是从 RGB 转换为 the HSV space

public int enlight(int color, float amount) {
  float[] hsv = new float[3];
  Color.colorToHSV(color, hsv);
  hsv[2] = Math.min(1.0f, amount * hsv[2]);
  return Color.HSVToColor(hsv);
}

然后您可以点亮一种颜色,只需增加 v(值)组件,然后在需要时使用相同的 Android API Color 转换回 RGB

【讨论】:

  • 好像还不错……我们需要把v的三个值都增加吗?
  • 不,单色,比如说green可以用RGB和HSV的形式表示。 20% 浅绿色 具有与 green 相同的 H 和 S 分量,但 V 大 20%(V 在 0.0 - 1.0 范围内)。请参阅链接的维基百科文章:页面底部有一张漂亮的表格
  • 我改变了饱和度 (hsv[1]),它给了我想要的东西。渐变不那么动态,但同时又很美,正是我想要的。
  • 这与我的回答中的功能完全相同,但有两次从 Color 到 HSV 的额外转换,反之亦然。与我的回答相比,我没有看到它的好处。
  • @htz 你没有使用 Android API,无论如何the results are different
【解决方案2】:

我做了一个简单的例子来向你展示一种可能的方法,它利用了 Color 类的getRGBColorComponents() 方法。

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Test extends JFrame {

public Test(Color c1, Color c2) {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(200, 200);
    setVisible(true);
    JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
    panel.add(new JLabel(createColorIcon(c1)));
    panel.add(new JLabel(createColorIcon(c2)));
    add(panel);
}

public ImageIcon createColorIcon(Color c) {
    int w = 44, h = 20;
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = bi.createGraphics();
    if (c != null) {
        g.setColor(c);
        g.fillRect(0, 0, w, h);
    } else {
        g.setColor(Color.GRAY);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.drawLine(1, 1, w - 2, h - 2);
        g.drawLine(1, h - 2, w - 2, 1);
    }
    g.setColor(Color.GRAY);
    g.drawRect(0, 0, w - 1, h - 1);
    g.dispose();
    return new ImageIcon(bi);
}

public static void main(String[] args) {

    Color c1 = Color.decode("0xFF0000");
    float[] f = c1.getRGBColorComponents(null);
    System.out.println(f.length);
    for (int i = 0; i < f.length; i++) {
        System.out.println(f[i]);
    }
    f[0] = f[0] * 0.8f;
    Color c2 = new Color(f[0],f[1],f[2]);
    new Test(c1,c2);

}

}

您只需调用getRGBColorComponents()方法,您就会得到一个数组,其中红色、绿色和蓝色的颜色值是介于 0.0 到 1.0 之间的浮点值,其中 int 值 255(或 0xFF)对应于1.0 浮点值。您只需将它与您选择的因子相乘,就像我在示例末尾所做的那样。

【讨论】:

    【解决方案3】:

    好像是这样的:

    int red     = Color.red(color);
    int green   = Color.green(color);
    int blue    = Color.blue(color);
    
    int secondColor = 0;
    int lighting    = 51; // from 0 to 255. The larger the number is the brighter second color
    
    if (red > green && red > blue)
        secondColor = Color.rgb(red, green - lighting, blue - lighting);
    else if (green > red && green > blue)
        secondColor = Color.rgb(red - lighting, green, blue - lighting);
    else if (blue > red && blue > green)
        secondColor = Color.rgb(red - lighting, green - lighting, blue);
    

    我应该测试它的所有颜色...


    更新:

    它有效,但是您需要设置一些其他条件来检查绿色和蓝色是否相等或红色和蓝色等.. 请放松@Raffaele 回答

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-19
      • 2011-03-31
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多