1 /* 2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This file is available and licensed under the following license: 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the distribution. 16 * - Neither the name of Oracle Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package ensemble.samples.graphics2d.images.imageoperator; 33 34 import javafx.application.Application; 35 import javafx.beans.InvalidationListener; 36 import javafx.beans.Observable; 37 import javafx.beans.property.DoubleProperty; 38 import javafx.beans.property.SimpleDoubleProperty; 39 import javafx.scene.Parent; 40 import javafx.scene.Scene; 41 import javafx.scene.image.Image; 42 import javafx.scene.image.ImageView; 43 import javafx.scene.image.PixelWriter; 44 import javafx.scene.image.WritableImage; 45 import javafx.scene.layout.StackPane; 46 import javafx.scene.paint.Color; 47 import javafx.stage.Stage; 48 49 /** 50 * A sample that demonstrates the use of two different constructors in the Image 51 * class. 52 * 53 * @sampleName Image Operation 54 * @preview preview.png 55 * @docUrl http://docs.oracle.com/javase/8/javafx/graphics-tutorial/image_ops.htm#JFXGR238 JavaFX Image Operations 56 * @playground gridSize (name="Grid Size", min=0, max=10) 57 * @playground hueFactor (name="Hue Factor", min=0, max=32) 58 * @playground hueOffset (name="Hue Offset", min=0, max=360) 59 * @see javafx.scene.image.Image 60 * @see javafx.scene.image.ImageView 61 * @see javafx.scene.image.PixelWriter 62 * @see javafx.scene.image.WritableImage 63 * 64 * @related /Graphics 2d/Images/Image Creation 65 * @related /Graphics 2d/Images/Image Properties 66 */ 67 public class ImageOperationApp extends Application { 68 private final DoubleProperty gridSize = new SimpleDoubleProperty(3.0); 69 public final DoubleProperty gridSizeProperty() { 70 return gridSize; 71 } 72 73 private final DoubleProperty hueFactor = new SimpleDoubleProperty(12.0); 74 public final DoubleProperty hueFactorProperty() { 75 return hueFactor; 76 } 77 78 private final DoubleProperty hueOffset = new SimpleDoubleProperty(240.0); 79 public final DoubleProperty hueOffsetProperty() { 80 return hueOffset; 81 } 82 83 private static void renderImage(WritableImage img, double gridSize, 84 double hueFactor, double hueOffset) { 85 PixelWriter pw = img.getPixelWriter(); 86 double w = img.getWidth(); 87 double h = img.getHeight(); 88 double xRatio = 0.0; 89 double yRatio = 0.0; 90 double hue = 0.0; 91 92 for (int y = 0; y < h; y++) { 93 for (int x = 0; x < w; x++) { 94 xRatio = x/w; 95 yRatio = y/h; 96 hue = Math.sin(yRatio*(gridSize*Math.PI)) * 97 Math.sin(xRatio*(gridSize*Math.PI)) * 98 Math.tan(hueFactor / 20.0) * 360.0 + hueOffset; 99 Color c = Color.hsb(hue, 1.0, 1.0); 100 pw.setColor(x, y, c); 101 } 102 } 103 } 104 public Parent createContent() { 105 StackPane root = new StackPane(); 106 final WritableImage img = new WritableImage(200, 200); 107 gridSize.addListener((Observable observable) -> { 108 renderImage(img, gridSize.doubleValue(), 109 hueFactor.doubleValue(), hueOffset.doubleValue()); 110 }); 111 hueFactor.addListener((Observable observable) -> { 112 renderImage(img, gridSize.doubleValue(), 113 hueFactor.doubleValue(), hueOffset.doubleValue()); 114 }); 115 hueOffset.addListener((Observable observable) -> { 116 renderImage(img, gridSize.doubleValue(), 117 hueFactor.doubleValue(), hueOffset.doubleValue()); 118 }); 119 renderImage(img, 3.0, 12.0, 240.0); 120 121 ImageView view = new ImageView(img); 122 root.getChildren().add(view); 123 124 return root; 125 } 126 127 @Override public void start(Stage primaryStage) throws Exception { 128 primaryStage.setScene(new Scene(createContent())); 129 primaryStage.show(); 130 } 131 132 /** Java main for when running without JavaFX launcher 133 * @param args command line arguments 134 */ 135 public static void main(String[] args) { 136 launch(args); 137 } 138 }