color.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,004 行 · 第 1/3 页

JAVA
1,004
字号

  /**
   * Converts from the HSB (hue, saturation, brightness) color model to the
   * RGB (red, green, blue) color model. The hue may be any floating point;
   * it's fractional portion is used to select the angle in the HSB model.
   * The saturation and brightness must be between 0 and 1. The result is
   * suitable for creating an RGB color with the one-argument constructor.
   *
   * @param hue the hue of the HSB value
   * @param saturation the saturation of the HSB value
   * @param brightness the brightness of the HSB value
   * @return the RGB value
   * @see #getRGB()
   * @see #Color(int)
   * @see ColorModel#getRGBdefault()
   */
  public static int HSBtoRGB(float hue, float saturation, float brightness)
  {
    if (saturation == 0)
      return convert(brightness, brightness, brightness, 0);
    if (saturation < 0 || saturation > 1 || brightness < 0 || brightness > 1)
      throw new IllegalArgumentException();
    hue = hue - (float) Math.floor(hue);
    int i = (int) (6 * hue);
    float f = 6 * hue - i;
    float p = brightness * (1 - saturation);
    float q = brightness * (1 - saturation * f);
    float t = brightness * (1 - saturation * (1 - f));
    switch (i)
      {
      case 0:
        return convert(brightness, t, p, 0);
      case 1:
        return convert(q, brightness, p, 0);
      case 2:
        return convert(p, brightness, t, 0);
      case 3:
        return convert(p, q, brightness, 0);
      case 4:
        return convert(t, p, brightness, 0);
      case 5:
        return convert(brightness, p, q, 0);
      default:
        throw new InternalError("impossible");
      }
  }

  /**
   * Converts from the RGB (red, green, blue) color model to the HSB (hue,
   * saturation, brightness) color model. If the array is null, a new one
   * is created, otherwise it is recycled. The results will be in the range
   * 0.0-1.0 if the inputs are in the range 0-255.
   *
   * @param red the red part of the RGB value
   * @param green the green part of the RGB value
   * @param blue the blue part of the RGB value
   * @param array an array for the result (at least 3 elements), or null
   * @return the array containing HSB value
   * @throws ArrayIndexOutOfBoundsException of array is too small
   * @see #getRGB()
   * @see #Color(int)
   * @see ColorModel#getRGBdefault()
   */
  public static float[] RGBtoHSB(int red, int green, int blue, float array[])
  {
    if (array == null)
      array = new float[3];
    // Calculate brightness.
    int min;
    int max;
    if (red < green)
      {
        min = red;
        max = green;
      }
    else
      {
        min = green;
        max = red;
      }
    if (blue > max)
      max = blue;
    else if (blue < min)
      min = blue;
    array[2] = max / 255f;
    // Calculate saturation.
    if (max == 0)
      array[1] = 0;
    else
      array[1] = (max - min) / max;
    // Calculate hue.
    if (array[1] == 0)
      array[0] = 0;
    else
      {
        float delta = (max - min) * 6;
        if (red == max)
          array[0] = (green - blue) / delta;
        else if (green == max)
          array[0] = 1 / 3 + (blue - red) / delta;
        else
          array[0] = 2 / 3 + (red - green) / delta;
        if (array[0] < 0)
          array[0]++;
      }
    return array;
  }

  /**
   * Returns a new instance of <code>Color</code> based on the specified
   * HSB values. The hue may be any floating point; it's fractional portion
   * is used to select the angle in the HSB model. The saturation and
   * brightness must be between 0 and 1.
   *
   * @param hue the hue of the HSB value
   * @param saturation the saturation of the HSB value
   * @param brightness the brightness of the HSB value
   * @return the new <code>Color</code> object
   */
  public static Color getHSBColor(float hue, float saturation,
                                  float brightness)
  {
    return new Color(HSBtoRGB(hue, saturation, brightness), false);
  }

  /**
   * Returns a float array with the red, green, and blue components, and the
   * alpha value, in the default sRGB space, with values in the range 0.0-1.0.
   * If the array is null, a new one is created, otherwise it is recycled.
   *
   * @param array the array to put results into (at least 4 elements), or null
   * @return the RGB components and alpha value
   * @throws ArrayIndexOutOfBoundsException if array is too small
   */
  public float[] getRGBComponents(float[] array)
  {
    if (array == null)
      array = new float[4];
    getRGBColorComponents(array);
    // Stupid serialization issues require this check.
    array[3] = (falpha == 0 && frgbvalue == null
                ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
    return array;
  }

  /**
   * Returns a float array with the red, green, and blue components, in the
   * default sRGB space, with values in the range 0.0-1.0. If the array is
   * null, a new one is created, otherwise it is recycled.
   *
   * @param array the array to put results into (at least 3 elements), or null
   * @return the RGB components
   * @throws ArrayIndexOutOfBoundsException if array is too small
   */
  public float[] getRGBColorComponents(float[] array)
  {
    if (array == null)
      array = new float[3];
    else if (array == frgbvalue)
      return array; // Optimization for getColorComponents(float[]).
    if (frgbvalue == null)
      {
        // Do not inline getRGB() to this.value, because of SystemColor.
        int value = getRGB();
        frgbvalue = new float[] { ((value & RED_MASK) >> 16) / 255f,
                                  ((value & GREEN_MASK) >> 8) / 255f,
                                  (value & BLUE_MASK) / 255f };
      }
    array[0] = frgbvalue[0];
    array[1] = frgbvalue[1];
    array[2] = frgbvalue[2];
    return array;
  }

  /**
   * Returns a float array containing the color and alpha components of this
   * color in the ColorSpace it was created with (the constructors which do
   * not take a ColorSpace parameter use a default sRGB ColorSpace). If the
   * array is null, a new one is created, otherwise it is recycled, and must
   * have at least one more position than components used in the color space.
   *
   * @param array the array to put results into, or null
   * @return the original color space components and alpha value
   * @throws ArrayIndexOutOfBoundsException if array is too small
   */
  public float[] getComponents(float[] array)
  {
    int numComponents = cs == null ? 3 : cs.getNumComponents();
    if (array == null)
      array = new float[1 + numComponents];
    getColorComponents(array);
    // Stupid serialization issues require this check.
    array[numComponents] = (falpha == 0 && frgbvalue == null
                            ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
    return array;
  }

  /**
   * Returns a float array containing the color components of this color in
   * the ColorSpace it was created with (the constructors which do not take
   * a ColorSpace parameter use a default sRGB ColorSpace). If the array is
   * null, a new one is created, otherwise it is recycled, and must have at
   * least as many positions as used in the color space.
   *
   * @param array the array to put results into, or null
   * @return the original color space components
   * @throws ArrayIndexOutOfBoundsException if array is too small
   */
  public float[] getColorComponents(float[] array)
  {
    int numComponents = cs == null ? 3 : cs.getNumComponents();
    if (array == null)
      array = new float[numComponents];
    if (fvalue == null) // If fvalue is null, cs should be null too.
      fvalue = getRGBColorComponents(frgbvalue);
    System.arraycopy(fvalue, 0, array, 0, numComponents);
    return array;
  }

  /**
   * Returns a float array containing the color and alpha components of this
   * color in the given ColorSpace. If the array is null, a new one is
   * created, otherwise it is recycled, and must have at least one more
   * position than components used in the color space.
   *
   * @param space the color space to translate to
   * @param array the array to put results into, or null
   * @return the color space components and alpha value
   * @throws ArrayIndexOutOfBoundsException if array is too small
   * @throws NullPointerException if space is null
   */
  public float[] getComponents(ColorSpace space, float[] array)
  {
    int numComponents = space.getNumComponents();
    if (array == null)
      array = new float[1 + numComponents];
    getColorComponents(space, array);
    // Stupid serialization issues require this check.
    array[numComponents] = (falpha == 0 && frgbvalue == null
                            ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha);
    return array;
  }

  /**
   * Returns a float array containing the color components of this color in
   * the given ColorSpace. If the array is null, a new one is created,
   * otherwise it is recycled, and must have at least as many positions as
   * used in the color space.
   *
   * @param space the color space to translate to
   * @return the color space components
   * @throws ArrayIndexOutOfBoundsException if array is too small
   * @throws NullPointerException if space is null
   */
  public float[] getColorComponents(ColorSpace space, float[] array)
  {
    float[] components = space.fromRGB(getRGBColorComponents(frgbvalue));
    if (array == null)
      return components;
    System.arraycopy(components, 0, array, 0, components.length);
    return array;
  }

  /**
   * Returns the color space of this color. Except for the constructor which
   * takes a ColorSpace argument, this will be an implementation of
   * ColorSpace.CS_sRGB.
   *
   * @return the color space
   */
  public ColorSpace getColorSpace()
  {
    return cs == null ? ColorSpace.getInstance(ColorSpace.CS_sRGB) : cs;
  }

  /**
   * Returns a paint context, used for filling areas of a raster scan with
   * this color. Since the color is constant across the entire rectangle, and
   * since it is always in sRGB space, this implementation returns the same
   * object, regardless of the parameters. Subclasses, however, may have a
   * mutable result.
   *
   * @param cm the requested color model, ignored
   * @param deviceBounds the bounding box in device coordinates, ignored
   * @param userBounds the bounding box in user coordinates, ignored
   * @param xform the bounds transformation, ignored
   * @param hints any rendering hints, ignored
   * @return a context for painting this solid color
   */
  public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
                                    Rectangle2D userBounds,
                                    AffineTransform xform,
                                    RenderingHints hints)
  {
    if (context == null)
      context = new ColorPaintContext(value);
    return context;
  }

  /**
   * Returns the transparency level of this color.
   *
   * @return one of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT}
   */
  public int getTransparency()
  {
    // Do not inline getRGB() to this.value, because of SystemColor.
    int alpha = getRGB() & ALPHA_MASK;
    return alpha == (255 << 24) ? OPAQUE : alpha == 0 ? BITMASK : TRANSLUCENT;
  }

  /**
   * Converts float values to integer value.
   *
   * @param red the red value
   * @param green the green value
   * @param blue the blue value
   * @param alpha the alpha value
   * @return the integer value made of 8-bit sections
   * @throws IllegalArgumentException if parameters are out of range 0.0-1.0
   */
  private static int convert(float red, float green, float blue, float alpha)
  {
    if (red < 0 || red > 1 || green < 0 || green > 1 || blue < 0 || blue > 1
        || alpha < 0 || alpha > 1)
      throw new IllegalArgumentException("Bad RGB values");
    int redval = Math.round(255 * red);
    int greenval = Math.round(255 * green);
    int blueval = Math.round(255 * blue);
    int alphaval = Math.round(255 * alpha);
    return (alphaval << 24) | (redval << 16) | (greenval << 8) | blueval;
  }
} // class Color

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?