344 lines
10 KiB
Java
344 lines
10 KiB
Java
/*DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
|
*
|
|
* Copyright 2006-2008. Tim Boudreau. All rights reserved.
|
|
*
|
|
* The contents of this file are subject to the terms of either the GNU
|
|
* General Public License Version 2 only ("GPL") or the Common
|
|
* Development and Distribution License("CDDL") (collectively, the
|
|
* "License"). You may not use this file except in compliance with the
|
|
* License. You can obtain a copy of the License at
|
|
* http://www.netbeans.org/cddl-gplv2.html. See the License for the
|
|
* specific language governing permissions and limitations under the
|
|
* License. When distributing the software, include this License Header
|
|
* Notice in each file and include the License file at
|
|
* nbbuild/licenses/CDDL-GPL-2-CP. This particular file is designated
|
|
* as subject to the "Classpath" exception as provided
|
|
* in the GPL Version 2 section of the License file that
|
|
* accompanied this code.
|
|
*/
|
|
|
|
package net.java.dev.colorchooser;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Dimension;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.Point;
|
|
import java.awt.geom.AffineTransform;
|
|
import java.awt.image.BufferedImage;
|
|
|
|
/*
|
|
* SpectrumImageImage.java
|
|
*
|
|
* Created on January 10, 2000, 4:54 PM
|
|
*/
|
|
/**
|
|
* This class is palette that uses an offscreen bitmap which contains a spectrum
|
|
* of color and hue. The direction of gradients and saturation are settable by
|
|
* arguments to the constructor.
|
|
*
|
|
* @author Tim Boudreau
|
|
*/
|
|
final class ContinuousPalette extends Palette {
|
|
public static final int SMALL_SPEC_WIDTH = 128;
|
|
public static final int SMALL_SPEC_HEIGHT = 64;
|
|
public static final int LARGE_SPEC_WIDTH = 200;
|
|
public static final int LARGE_SPEC_HEIGHT = 100;
|
|
public static final int SPEC_IMAGE_COUNT = 8;
|
|
|
|
private BufferedImage img = null;
|
|
|
|
/**
|
|
* Set true when the bitmap has been built. Bitmap is built on the first
|
|
* call to paintTo(), or the first call to PaintTo() subsequent to a
|
|
* property being changed that affects the contents of the bitmap.
|
|
*/
|
|
private boolean initialized = false;
|
|
|
|
/**
|
|
* Holds value of property saturation. Determines the maximum saturation
|
|
* level present in the bitmap
|
|
*/
|
|
private float saturation = 1f;
|
|
/**
|
|
* Holds value of property verticalHue. When set true, hue rotation is
|
|
* vertical
|
|
*/
|
|
private boolean verticalHue = true;
|
|
/** Default value for gray strip on horizontal hue gradients */
|
|
private float grayStripSize = 0.05f;
|
|
private String name;
|
|
|
|
/**
|
|
* Creates a ContinuousPalette object with user specifiable size and
|
|
* saturation and the default horizontal hue gradient direction.
|
|
*/
|
|
ContinuousPalette(final String name, final int width, final int height,
|
|
final float saturation) {
|
|
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
|
this.setSaturation(saturation);
|
|
this.name = name;
|
|
}
|
|
|
|
/**
|
|
* Creates a ContinuousPalette object with user specifiable size, saturation
|
|
* and hue gradient direction.
|
|
*
|
|
* @param width
|
|
* The width of the image to be created
|
|
* @param height
|
|
* The height of the image to be created
|
|
* @param saturation
|
|
* The saturation of the image to be created
|
|
* @param vHue
|
|
* Sets vertical or horizontal hue gradient
|
|
*/
|
|
private ContinuousPalette(final String name, final int width,
|
|
final int height, final float saturation, final boolean vHue) {
|
|
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
|
this.setSaturation(saturation);
|
|
this.verticalHue = vHue;
|
|
this.name = name;
|
|
}
|
|
|
|
/**
|
|
* Builds the spectrum bitmap in memory by iterating through all of the
|
|
* pixels and calling getColorAt for each.
|
|
*/
|
|
protected void initImage() {
|
|
int currColor;
|
|
for (int x = 0; x < img.getWidth(); x++) {
|
|
for (int y = 0; y < img.getHeight(); y++) {
|
|
currColor = getColorAt(x, y).getRGB();
|
|
img.setRGB(x, y, currColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Public implementation of InitImage() - tests whether spectrum image has
|
|
* already been built and only builds it if needed.
|
|
*/
|
|
public final void initializeImage() {
|
|
if (!initialized)
|
|
initImage();
|
|
}
|
|
|
|
/**
|
|
* Paints the image at Coordinates 0,0 on the graphics context passed to it.
|
|
*
|
|
* @param g
|
|
* A graphics context to be painted into
|
|
*/
|
|
@Override
|
|
public void paintTo(final java.awt.Graphics g) {
|
|
if (g != null) {
|
|
initializeImage();
|
|
((Graphics2D) g).drawRenderedImage(img, AffineTransform
|
|
.getTranslateInstance(0, 0));
|
|
initialized = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the color a pixel at a given point should be as an RGB int. Color
|
|
* is calculated as follows - Saturation is constant up to the halfway point
|
|
* in the brightness gradient direction, and brightness rises. At 100%
|
|
* brightness, you have a fully saturated color. From this point on,
|
|
* Brightness is constant at 1.0 and saturation drops linearly from the
|
|
* saturation property value down to 0.
|
|
*
|
|
* @param x
|
|
* The X coordinate for which a color value is desired
|
|
* @param y
|
|
* The Y coordinate for which a color value is desired
|
|
*/
|
|
@Override
|
|
public java.awt.Color getColorAt(final int x, final int y) {
|
|
float hue;
|
|
float brightness;
|
|
float workingSaturation;
|
|
final boolean inGrayStrip = ((float) y) / img.getHeight() > (1 - grayStripSize);
|
|
if (verticalHue) {
|
|
hue = ((float) y) / img.getHeight(); // Hue value from 0-1 based on
|
|
// y position
|
|
brightness = ((float) x) / img.getWidth(); // base brightness value
|
|
// 0-1 based on x
|
|
// location
|
|
} else {
|
|
if (inGrayStrip)
|
|
return grayValueFromX(x);
|
|
hue = 1 - (((float) x) / img.getWidth()); // subtract from 1 so
|
|
// lightest color are at
|
|
// top
|
|
brightness = 1 - ((float) y) / img.getHeight();
|
|
}
|
|
brightness = brightness * 2; // brightness increases to the halfway
|
|
// point along the brightening axis.
|
|
if (brightness > 1) { // beyond that point, saturation goes down so
|
|
// color moves toward white
|
|
workingSaturation = saturation - ((brightness - 1) * saturation); // if
|
|
// we're
|
|
// past
|
|
// the
|
|
// halfway
|
|
// point,
|
|
brightness = 1; // we're decrementing saturation
|
|
} else {
|
|
workingSaturation = saturation;
|
|
}
|
|
final java.awt.Color newColor = java.awt.Color.getHSBColor(hue,
|
|
workingSaturation, brightness);
|
|
return newColor;
|
|
}
|
|
|
|
public java.awt.Color colorFromPoint(final Point p) {
|
|
final int x = new Double(p.getX()).intValue();
|
|
final int y = new Double(p.getY()).intValue();
|
|
return getColorAt(x, y);
|
|
}
|
|
|
|
/**
|
|
* Called by InitImage() to draw the grayscale strip at the bottom of
|
|
* horizontal-hue spectrum images. Returns a grayscale value based on the
|
|
* width of the image, when called with a horizontal coordinate.
|
|
*
|
|
* @param x
|
|
* The x coordinate for which a grayscale value is desired
|
|
* @return The grayscale value (expressed as an RGB integer value)
|
|
*/
|
|
protected java.awt.Color grayValueFromX(final int x) {
|
|
final java.awt.Color newColor = java.awt.Color.getHSBColor(0, 0,
|
|
((float) x) / img.getWidth());
|
|
return newColor;
|
|
}
|
|
|
|
/**
|
|
* Getter for property saturation. Saturation defines the base saturation
|
|
* for all colors in the image. Setting it to less that 1 causes the colors
|
|
* to be more desaturated in the resulting bufferedImage.
|
|
*
|
|
* @return Returns the maximum saturation value for any colors to be
|
|
* generated in the bufferedImage.
|
|
*/
|
|
public float getSaturation() {
|
|
return saturation;
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum saturation for any colors in the image. Constrained from
|
|
* 0-1. Changing this property will cause the image to be regenerated the
|
|
* next time it is needed, or the next time initializeImage() is called.
|
|
*
|
|
* @param saturation
|
|
* New value of property saturation.
|
|
*/
|
|
public void setSaturation(final float saturation) {
|
|
if (this.saturation != saturation) {
|
|
this.saturation = saturation;
|
|
doChange();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter for property verticalHue.
|
|
*
|
|
* @return Value of property verticalHue.
|
|
*/
|
|
public boolean isVerticalHue() {
|
|
return verticalHue;
|
|
}
|
|
|
|
/**
|
|
* Setter for property verticalHue.
|
|
*
|
|
* @param verticalHue
|
|
* New value of property verticalHue.
|
|
*/
|
|
public void setVerticalHue(final boolean verticalHue) {
|
|
if (this.verticalHue != verticalHue) {
|
|
this.verticalHue = verticalHue;
|
|
doChange();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called when a parameter is changed that requires that the spectrum image
|
|
* be rebuilt, so that the next time the image is asked for, it will be.
|
|
*/
|
|
protected void doChange() {
|
|
initialized = false;
|
|
}
|
|
|
|
/**
|
|
* Setter for the grayStripSize property, which determines the percentage
|
|
* (expressed as a float between 0 and 1) of the image height taken up by
|
|
* the grayscale strip.
|
|
*/
|
|
public void setGrayStripSize(final float grayStripSize) {
|
|
float workingGrayStripSize = grayStripSize;
|
|
if (workingGrayStripSize > 1)
|
|
workingGrayStripSize = 1; // handle screwy > 1 values just in case
|
|
if (workingGrayStripSize != grayStripSize) {
|
|
this.grayStripSize = grayStripSize;
|
|
doChange();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter for the GrayStripSize property, which returns the percentage
|
|
* (expressed as a float between 0 and 1) of the height of the image taken
|
|
* up by the gray scale strip for selecting non-colored pixels.
|
|
*/
|
|
public float getGrayStripSize() {
|
|
return this.grayStripSize;
|
|
}
|
|
|
|
/**
|
|
* Returns the size of the image as a java.awt.Dimension object.
|
|
*/
|
|
@Override
|
|
public Dimension getSize() {
|
|
return new Dimension(img.getWidth(), img.getHeight());
|
|
}
|
|
|
|
@Override
|
|
public String getNameAt(final int x, final int y) {
|
|
final Color c = getColorAt(x, y);
|
|
final StringBuffer sb = new StringBuffer();
|
|
sb.append(c.getRed());
|
|
sb.append(','); // NOI18N
|
|
sb.append(c.getGreen());
|
|
sb.append(','); // NOI18N
|
|
sb.append(c.getBlue());
|
|
return sb.toString();
|
|
}
|
|
|
|
private static Palette[] defaultPalettes = null;
|
|
|
|
/** Create a default set of continuous palettes to use */
|
|
public static Palette[] createDefaultPalettes() {
|
|
if (defaultPalettes == null) {
|
|
defaultPalettes = new Palette[] {
|
|
new ContinuousPalette("satLarge", LARGE_SPEC_WIDTH,
|
|
LARGE_SPEC_HEIGHT, 1f, false), // NOI18N
|
|
new ContinuousPalette("unsatLarge", LARGE_SPEC_WIDTH,
|
|
LARGE_SPEC_HEIGHT, 0.4f, false), // NOI18N
|
|
new ContinuousPalette("satLargeHoriz", LARGE_SPEC_WIDTH,
|
|
LARGE_SPEC_HEIGHT, 1f, true), // NOI18N
|
|
new ContinuousPalette("unsatLargeHoriz", LARGE_SPEC_WIDTH,
|
|
LARGE_SPEC_HEIGHT, 0.4f, true) // NOI18N
|
|
};
|
|
}
|
|
return defaultPalettes;
|
|
}
|
|
|
|
@Override
|
|
public String getDisplayName() {
|
|
return ColorChooser.getString(name);
|
|
}
|
|
|
|
@Override
|
|
public void setSize(final int w, final int h) {
|
|
}
|
|
}
|