1 /* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.scene.effect; 27 28 import javafx.beans.property.DoubleProperty; 29 import javafx.beans.property.DoublePropertyBase; 30 import javafx.beans.property.ObjectProperty; 31 import javafx.scene.Node; 32 33 import com.sun.javafx.util.Utils; 34 import com.sun.javafx.effect.EffectDirtyBits; 35 import com.sun.javafx.geom.BaseBounds; 36 import com.sun.javafx.geom.transform.BaseTransform; 37 import com.sun.javafx.scene.BoundsAccessor; 38 39 40 /** 41 * An effect that allows for per-pixel adjustments of hue, saturation, 42 * brightness, and contrast. 43 * 44 * <p> 45 * Example: 46 * <pre><code> 47 * ColorAdjust colorAdjust = new ColorAdjust(); 48 * colorAdjust.setContrast(0.1); 49 * colorAdjust.setHue(-0.05); 50 * colorAdjust.setBrightness(0.1); 51 * colorAdjust.setSaturation(0.2); 52 * 53 * Image image = new Image("boat.jpg"); 54 * ImageView imageView = new ImageView(image); 55 * imageView.setFitWidth(200); 56 * imageView.setPreserveRatio(true); 57 * imageView.setEffect(colorAdjust); 58 * </pre></code> 59 * <p> The code above applied on this image: </p> 60 * <p> 61 * <img src="doc-files/photo.png"/> 62 * </p> 63 * <p> produces the following: </p> 64 * <p> 65 * <img src="doc-files/coloradjust.png"/> 66 * </p> 67 * @since JavaFX 2.0 68 */ 69 public class ColorAdjust extends Effect { 70 /** 71 * Creates a new instance of ColorAdjust with default parameters. 72 */ 73 public ColorAdjust() {} 74 75 /** 76 * Creates a new instance of ColorAdjust with the specified hue, saturation, 77 * brightness, and contrast. 78 * @param hue the hue adjustment value 79 * @param saturation the saturation adjustment value 80 * @param brightness the brightness adjustment value 81 * @param contrast the contrast adjustment value 82 * @since JavaFX 2.1 83 */ 84 public ColorAdjust(double hue, 85 double saturation, 86 double brightness, 87 double contrast) { 88 setBrightness(brightness); 89 setContrast(contrast); 90 setHue(hue); 91 setSaturation(saturation); 92 } 93 94 @Override 95 com.sun.scenario.effect.ColorAdjust impl_createImpl() { 96 return new com.sun.scenario.effect.ColorAdjust(); 97 }; 98 /** 99 * The input for this {@code Effect}. 100 * If set to {@code null}, or left unspecified, a graphical image of 101 * the {@code Node} to which the {@code Effect} is attached will be 102 * used as the input. 103 * @defaultValue null 104 */ 105 private ObjectProperty<Effect> input; 106 107 108 public final void setInput(Effect value) { 109 inputProperty().set(value); 110 } 111 112 public final Effect getInput() { 113 return input == null ? null : input.get(); 114 } 115 116 public final ObjectProperty<Effect> inputProperty() { 117 if (input == null) { 118 input = new EffectInputProperty("input"); 119 } 120 return input; 121 } 122 123 @Override 124 boolean impl_checkChainContains(Effect e) { 125 Effect localInput = getInput(); 126 if (localInput == null) 127 return false; 128 if (localInput == e) 129 return true; 130 return localInput.impl_checkChainContains(e); 131 } 132 133 /** 134 * The hue adjustment value. 135 * <pre> 136 * Min: -1.0 137 * Max: +1.0 138 * Default: 0.0 139 * Identity: 0.0 140 * </pre> 141 * @defaultValue 0.0 142 */ 143 private DoubleProperty hue; 144 145 146 public final void setHue(double value) { 147 hueProperty().set(value); 148 } 149 150 public final double getHue() { 151 return hue == null ? 0 : hue.get(); 152 } 153 154 public final DoubleProperty hueProperty() { 155 if (hue == null) { 156 hue = new DoublePropertyBase() { 157 158 @Override 159 public void invalidated() { 160 markDirty(EffectDirtyBits.EFFECT_DIRTY); 161 effectBoundsChanged(); 162 } 163 164 @Override 165 public Object getBean() { 166 return ColorAdjust.this; 167 } 168 169 @Override 170 public String getName() { 171 return "hue"; 172 } 173 }; 174 } 175 return hue; 176 } 177 178 /** 179 * The saturation adjustment value. 180 * <pre> 181 * Min: -1.0 182 * Max: +1.0 183 * Default: 0.0 184 * Identity: 0.0 185 * </pre> 186 * @defaultValue 0.0 187 */ 188 private DoubleProperty saturation; 189 190 191 public final void setSaturation(double value) { 192 saturationProperty().set(value); 193 } 194 195 public final double getSaturation() { 196 return saturation == null ? 0 : saturation.get(); 197 } 198 199 public final DoubleProperty saturationProperty() { 200 if (saturation == null) { 201 saturation = new DoublePropertyBase() { 202 203 @Override 204 public void invalidated() { 205 markDirty(EffectDirtyBits.EFFECT_DIRTY); 206 effectBoundsChanged(); 207 } 208 209 @Override 210 public Object getBean() { 211 return ColorAdjust.this; 212 } 213 214 @Override 215 public String getName() { 216 return "saturation"; 217 } 218 }; 219 } 220 return saturation; 221 } 222 223 /** 224 * The brightness adjustment value. 225 * <pre> 226 * Min: -1.0 227 * Max: +1.0 228 * Default: 0.0 229 * Identity: 0.0 230 * </pre> 231 * @defaultValue 0.0 232 */ 233 private DoubleProperty brightness; 234 235 236 public final void setBrightness(double value) { 237 brightnessProperty().set(value); 238 } 239 240 public final double getBrightness() { 241 return brightness == null ? 0 : brightness.get(); 242 } 243 244 public final DoubleProperty brightnessProperty() { 245 if (brightness == null) { 246 brightness = new DoublePropertyBase() { 247 248 @Override 249 public void invalidated() { 250 markDirty(EffectDirtyBits.EFFECT_DIRTY); 251 effectBoundsChanged(); 252 } 253 254 @Override 255 public Object getBean() { 256 return ColorAdjust.this; 257 } 258 259 @Override 260 public String getName() { 261 return "brightness"; 262 } 263 }; 264 } 265 return brightness; 266 } 267 268 /** 269 * The contrast adjustment value. 270 * <pre> 271 * Min: -1.0 272 * Max: +1.0 273 * Default: 0.0 274 * Identity: 0.0 275 * </pre> 276 * @defaultValue 0.0 277 */ 278 private DoubleProperty contrast; 279 280 281 public final void setContrast(double value) { 282 contrastProperty().set(value); 283 } 284 285 public final double getContrast() { 286 return contrast == null ? 0 : contrast.get(); 287 } 288 289 public final DoubleProperty contrastProperty() { 290 if (contrast == null) { 291 contrast = new DoublePropertyBase() { 292 293 @Override 294 public void invalidated() { 295 markDirty(EffectDirtyBits.EFFECT_DIRTY); 296 effectBoundsChanged(); 297 } 298 299 @Override 300 public Object getBean() { 301 return ColorAdjust.this; 302 } 303 304 @Override 305 public String getName() { 306 return "contrast"; 307 } 308 }; 309 } 310 return contrast; 311 } 312 313 @Override 314 void impl_update() { 315 Effect localInput = getInput(); 316 if (localInput != null) { 317 localInput.impl_sync(); 318 } 319 320 com.sun.scenario.effect.ColorAdjust peer = 321 (com.sun.scenario.effect.ColorAdjust) impl_getImpl(); 322 peer.setInput(localInput == null ? null : localInput.impl_getImpl()); 323 peer.setHue((float)Utils.clamp(-1, getHue(), 1)); 324 peer.setSaturation((float)Utils.clamp(-1, getSaturation(), 1)); 325 peer.setBrightness((float)Utils.clamp(-1, getBrightness(), 1)); 326 peer.setContrast((float)Utils.clamp(-1, getContrast(), 1)); 327 } 328 329 /** 330 * @treatAsPrivate implementation detail 331 * @deprecated This is an internal API that is not intended for use and will be removed in the next version 332 */ 333 @Deprecated 334 @Override 335 public BaseBounds impl_getBounds(BaseBounds bounds, 336 BaseTransform tx, 337 Node node, 338 BoundsAccessor boundsAccessor) { 339 return getInputBounds(bounds, tx, node, boundsAccessor, getInput()); 340 } 341 342 /** 343 * @treatAsPrivate implementation detail 344 * @deprecated This is an internal API that is not intended for use and will be removed in the next version 345 */ 346 @Deprecated 347 @Override 348 public Effect impl_copy() { 349 ColorAdjust ca = new ColorAdjust(this.getHue(), this.getSaturation(), 350 this.getBrightness(), this.getContrast()); 351 ca.setInput(ca.getInput()); 352 return ca; 353 } 354 }