javajavafxcolorspixel-shader

Change shade of color of each shape


I have the following image and I need to change each shapes color to green but each can have a different shade of green. I am unsure how to do this. I have an idea of how to do it with the whole image by changing pixel color, but not part of the image.

I am very new to javafx so please keep that in mind.

image


Solution

  • The easiest way to achieve that is to generate the image yourself and add each rectangle individually. In this case you can set the color for each rectangle independently:

    public class MyApp extends Application {
        @Override
        public void start(Stage primaryStage) {
            Group root = new Group();
            Scene scene = new Scene(root, 430, 230, Color.WHITE);
    
            List<Rectangle> rectangles = new ArrayList<>();
    
            int width = 100;
            int height = 50;
            int pad = 6;
    
            // first row
            rectangles.add(createRect(pad, pad, width, height, Color.GREEN));
            rectangles.add(createRect(pad + (width + pad), pad, width, height, Color.GREEN.brighter()));
            rectangles.add(createRect(pad + (width + pad) * 2, pad, width, height, Color.GREEN.darker()));
            rectangles.add(createRect(pad + (width + pad) * 3, pad, width, height, Color.GREEN));
    
            // second row
            rectangles.add(createRect(pad + (width + pad) * 0.5, pad + (height + pad), width, height, Color.GREEN.brighter()));
            rectangles.add(createRect(pad + (width + pad) * 1.5, pad + (height + pad), width, height, Color.GREEN));
            rectangles.add(createRect(pad + (width + pad) * 2.5, pad + (height + pad), width, height, Color.GREEN.darker()));
    
            // third row
            rectangles.add(createRect(pad + (width + pad), pad + (height + pad) * 2, width, height, Color.GREEN.darker()));
            rectangles.add(createRect(pad + (width + pad) * 2, pad + (height + pad) * 2, width, height, Color.GREEN));
    
            // last row
            rectangles.add(createRect(pad + (width + pad) * 1.5, pad + (height + pad) * 3, width, height, Color.GREEN.brighter()));
    
            root.getChildren().addAll(rectangles);
    
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        private Rectangle createRect(double x, double y, double width, double height, Color color) {
            Rectangle rectangle = new Rectangle(x, y, width, height);
            rectangle.setStroke(Color.BLACK);
            rectangle.setFill(color);
            return rectangle;
        }
    }
    

    The result would be the following:

    image result

    In my example I only used three different green shades, but you can set the color for each rectangle on your own and create gradients or what ever you like. Just replace Color.GREEN with new Color(0.0f, 0.7f, 0.0f, 1f) and adjust the parameters for your needs.

    Hope that helps.

    EDIT:

    If you want to use the generated Node as image you can use the Node.snapshot method to create an image:

    WritableImage snapshot = root.snapshot(new SnapshotParameters(), null);
    

    If you want to replace the original rectangles with the image you can use the following:

    root.getChildren().clear();
    ImageView imageView = new ImageView(snapshot);
    imageView.setX(pad);
    imageView.setY(pad);
    root.getChildren().add(imageView);
    

    To save the image as file you can use:

    ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "PNG", new File("/path/to/image.png"));