/* * This file is part of JGrasstools (http://www.jgrasstools.org) * (C) HydroloGIS - www.hydrologis.com * * JGrasstools is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.jgrasstools.gears.utils.colors; import java.awt.Color; import java.util.ArrayList; import java.util.List; /** * A color interpolation helper class. * * @author Andrea Antonello (www.hydrologis.com) */ public class ColorInterpolator { private Color[] colors; private double[] values; private double min; private double max; public ColorInterpolator( Color[] colors, double[] values, int alpha ) { this.colors = colors; this.values = values; min = values[0]; max = values[values.length - 1]; } public ColorInterpolator( String colorTableName, double min, double max, Integer alpha ) { this.min = min; this.max = max; createColortableArrays(colorTableName, min, max, alpha); } /** * Get the color of the defined table by its value. * * @param value the value. * @return the interpolated color. */ public Color getColorFor( double value ) { if (value <= min) { return colors[0]; } else if (value >= max) { return colors[colors.length - 1]; } else { for( int i = 1; i < colors.length; i++ ) { double v1 = values[i - 1]; double v2 = values[i]; if (value < v2) { double v = (value - v1) / (v2 - v1); Color interpolateColor = interpolateColor(colors[i - 1], colors[i], (float) v); return interpolateColor; } } return colors[colors.length - 1]; } } private void createColortableArrays( String colorTableName, double min, double max, Integer alpha ) { int a = 255; if (alpha != null) { a = alpha; } List<Color> colorList = new ArrayList<Color>(); String tableString = new DefaultTables().getTableString(colorTableName); String[] split = tableString.split("\n"); int length = split.length - 1; double delta = (max - min) / length; values = new double[split.length]; for( int i = 0; i < split.length; i++ ) { values[i] = min + i * delta; } List<Double> newValues = null; // if necessary for( String line : split ) { if (line.startsWith("#")) { //$NON-NLS-1$ continue; } String[] lineSplit = line.trim().split("\\s+"); //$NON-NLS-1$ if (lineSplit.length == 3) { int r = Integer.parseInt(lineSplit[0]); int g = Integer.parseInt(lineSplit[1]); int b = Integer.parseInt(lineSplit[2]); colorList.add(new Color(r, g, b, a)); } else if (lineSplit.length == 8) { if (newValues == null) { newValues = new ArrayList<Double>(); } // also value are provided, rewrite input values double v1 = Double.parseDouble(lineSplit[0]); int r1 = Integer.parseInt(lineSplit[1]); int g1 = Integer.parseInt(lineSplit[2]); int b1 = Integer.parseInt(lineSplit[3]); colorList.add(new Color(r1, g1, b1, a)); newValues.add(v1); double v2 = Double.parseDouble(lineSplit[4]); int r2 = Integer.parseInt(lineSplit[5]); int g2 = Integer.parseInt(lineSplit[6]); int b2 = Integer.parseInt(lineSplit[7]); colorList.add(new Color(r2, g2, b2, a)); newValues.add(v2); } else if (lineSplit.length == 4) { if (newValues == null) { newValues = new ArrayList<Double>(); } // also value are provided, rewrite input values double v1 = Double.parseDouble(lineSplit[0]); int r1 = Integer.parseInt(lineSplit[1]); int g1 = Integer.parseInt(lineSplit[2]); int b1 = Integer.parseInt(lineSplit[3]); colorList.add(new Color(r1, g1, b1, a)); newValues.add(v1); } } colors = colorList.toArray(new Color[0]); if (newValues != null) { // redefine values values = new double[newValues.size()]; for( int i = 0; i < newValues.size(); i++ ) { values[i] = newValues.get(i); } } } /** * Interpolate a color at a given fraction between 0 and 1. * * @param color1 start color. * @param color2 end color. * @param fraction the fraction to interpolate. * @return the new color. */ public static Color interpolateColor( Color color1, Color color2, float fraction ) { float int2Float = 1f / 255f; fraction = Math.min(fraction, 1f); fraction = Math.max(fraction, 0f); float r1 = color1.getRed() * int2Float; float g1 = color1.getGreen() * int2Float; float b1 = color1.getBlue() * int2Float; float a1 = color1.getAlpha() * int2Float; float r2 = color2.getRed() * int2Float; float g2 = color2.getGreen() * int2Float; float b2 = color2.getBlue() * int2Float; float a2 = color2.getAlpha() * int2Float; float deltaR = r2 - r1; float deltaG = g2 - g1; float deltaB = b2 - b1; float deltaA = a2 - a1; float red = r1 + (deltaR * fraction); float green = g1 + (deltaG * fraction); float blue = b1 + (deltaB * fraction); float alpha = a1 + (deltaA * fraction); red = Math.min(red, 1f); red = Math.max(red, 0f); green = Math.min(green, 1f); green = Math.max(green, 0f); blue = Math.min(blue, 1f); blue = Math.max(blue, 0f); alpha = Math.min(alpha, 1f); alpha = Math.max(alpha, 0f); return new Color(red, green, blue, alpha); } }