All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.image.ColorCurve Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2012 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.day.image;

import java.awt.Color;

/**
 * The ColorCurve class is a container to provide color and tonality
 * information. The main use of instances of this class is done in the
 * {@link MultitoneOp} class, which uses instances of this class to convey
 * information of colors and tonality of those colors to mix together.
 * 

* Instances of this class contain a Color value and a tonality * curve, which is a 256 element array of intensity values in the range [0..1], * where 0 is no application of this color and 1 is full color intensity. The * elements of the array map to image luminance, where element 0 is taken for * pixels with most luminance and element 256 is taken for pixels with no * luminance. * * @version $Revision$, $Date$ * @author fmeschbe * @since echidna * @audience wad */ public class ColorCurve { /** The number of levels supported by instances of this class */ public static final int MAX_LEVEL = 256; /** * The default color curve if none is explicitly defined. This maps input * luminance levels to the same output level. */ private static final float[] IDENTITY_CURVE; /** The color of this instance */ private final Color color; // build the identity mapping table static { IDENTITY_CURVE = new float[MAX_LEVEL]; for (int i=0; i < MAX_LEVEL; i++) { IDENTITY_CURVE[i] = (float) i / 256; } } /** * The color curve for this instance or null if this * instances */ private final float[] curve; /** * Creates a copy of the ColorCurve instance. This copy * constructor copies the values of the other instance. That is external * modification of thos values has no influence on the newly created * instance. * * @param colorCurve */ public ColorCurve(ColorCurve colorCurve) { this.color = colorCurve.color; this.curve = colorCurve.curve == null ? null : (float[]) colorCurve.curve.clone(); } /** * Creates a ColorCurve with the given color and the default * mapping. The default mapping maps luminosity levels to the same intensity * levels. * * @param color The color to set in this ColorCurve. */ public ColorCurve(Color color) { this.color = color; this.curve = IDENTITY_CURVE; } /** * Creates a ColorCurve with the given color and an evenly * spaced interval table based on list of intensity points. *

* Each entry of the curve parameter is in the range [0..1] and the length * of the array is in the interval [2..256]. If the array has less than * two entries it is ignored and the identity mapping is taken, if either * an entry value is out of range or the curve array is longer than 256 * entries, the result is undefined. * * @param color The color described by this descriptor * @param curve The intensity perecentages for equally distributed * intervals or null to use the identity map. */ public ColorCurve(Color color, float[] curve) { this.color = color; if (curve == null || curve.length < 2) { this.curve = IDENTITY_CURVE; } else { this.curve = evenlySpacedCurve(curve); } } /** * Creates a ColorCurve with the given color and an interval * table based on list of intensity points where the interval distances * is also specified. *

* Each entry of the curve parameter is in the range [0..1] and the length * of the array is in the interval [2..256]. If the array has less than * two entries it is ignored and the identity mapping is taken, if either * an entry value is out of range or the curve array is longer than 256 * entries, the result is undefined. *

* The intervals array must contain the one elements less than the curve * array, that is the predicate * curve.length - 1 == intervals.length must be * true. If the intervals array is smaller or bigger than that, * it is ignored and the points are evenyl spaced ! *

* The sum of entries of the intervals array defines the relative size of * each interval. For example if the sum of the entries is 11, the first * entry is 1, then the first intervall will take 23 steps, which is * 256 * 1/11 because each step is 1/11th of the full range of 256. * * @param color The color described by this descriptor * @param curve The intensity perecentages for the intervals or * null to use the identity map (in which case the * intervals argument is ignored). * @param intervals Normalized intervalls of curve values or * null to evenly space the itensity levels * . */ public ColorCurve(Color color, float[] curve, float intervals[]) { this.color = color; if (curve == null || curve.length < 2) { this.curve = IDENTITY_CURVE; } else { this.curve = intervalCurve(curve, intervals); } } /** * Returns the color associated with this instance. * @return the color associated with this instance. */ public Color getColor() { return color; } /** * Returns the intensity level for the given level. * * @param step The luminosity level for which to return this instances * intensity level. * * @return The intensity level of this instance for the given luminosity. * * @throws IndexOutOfBoundsException if step is less than 0 or higher than * {@link #MAX_LEVEL}. */ public float getLevel(int step) { return curve[step]; } /** * Creates a curve vector which evenly spaces the curve gradient intervals. * * @param curve The curve gradient points to be distributed. * * @return The curve vector with evenly spaced gradient intervalls. */ private float[] evenlySpacedCurve(float[] curve) { // create an intervals array, which evenly spaces the curve data float[] intervals = new float[curve.length-1]; for (int i=0; i < intervals.length; i++) { intervals[i] = 1; } // now use the interval parametrized method return intervalCurve(curve, intervals); } /** * Creates a curve vector, whose curve gradients are distributed according * to the intervalls array. The array contains normalized values of relative * intervall size. For example, if the sum of all entries in the intervals * array is 11 and the first entry is 1, the first intervall takes 23 * steps which is 256 * 1 / 11. *

* If the intervals list is null or does not contain one * element less than then curve list, the curve points are evenly distributed * as if the method {@link #evenlySpacedCurve(float[] curve)} would be * called. * * @param curve The curve gradient points to be distributed * @param intervals The normalized distribution list * * @return The curve vector with gradient intervalls as specified. */ private float[] intervalCurve(float[] curve, float intervals[]) { // check whether the intervalls array is correct, else use evenly spaced if (intervals == null || intervals.length != curve.length-1) { return evenlySpacedCurve(curve); } // find the normalization factor, which is the sum of all interval entries. float factor = 0; for (int i=0; i < intervals.length; i++) { factor += intervals[i]; } float[] res = new float[MAX_LEVEL]; int resI = 0; float level1 = curve[0]; for (int i=1; i < curve.length; i++) { float level0 = level1; float interval = intervals[i-1] * MAX_LEVEL / factor; int end = (int) (resI + interval + .5f); if (end > MAX_LEVEL || i == curve.length-1) { end = MAX_LEVEL; } level1 = curve[i]; float step = (level1 - level0) / (end - resI); for ( ; resI < end; resI++) { res[resI] = level0; level0 += step; } } return res; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy