Does javafx have a function to "fill" arbitrary shapes?

Can someone please help me figure out how to color different regions of an image (PNG) using JavaFX? The image is currently displayed in an ImageView:

https://i.sstatic.net/RVhE4.jpg

I'm looking to color region 1 blue, the second one red, and the last two purple. Is there a function in JavaFX similar to Windows Paint's bucket tool that can fill areas with specific colors within borders?

Answer №1

Recommended Technique

An effective approach would involve implementing a flood fill algorithm.

Code Example

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.image.*;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.util.Stack;

public class UnleashTheKraken extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(final Stage stage) {
        Image original = new Image(
            "http://s12.postimg.org/wofhjvy2h/image_2.jpg"
        );

        WritableImage updated = new WritableImage(
                original.getPixelReader(),
                (int) original.getWidth(),
                (int) original.getHeight()
        );

        Kraken kraken = new Kraken(updated, Color.WHITE);
        kraken.unleash(new Point2D(40,   40), Color.BLUE);
        kraken.unleash(new Point2D(40,  100), Color.RED);
        kraken.unleash(new Point2D(100, 100), Color.GREEN);
        kraken.unleash(new Point2D(120,  40), Color.YELLOW);

        ImageView originalView = new ImageView(original);
        ImageView filledView   = new ImageView(updated);

        HBox layout = new HBox(10, originalView, filledView);
        layout.setPadding(new Insets(10));
        stage.setScene(new Scene(layout));
        stage.show();
    }

    class Kraken {
        private final WritableImage img;
        private final Color targetColor;

        // color matching tolerance level (from 0 to 1);
        private final double E = 0.3;

        public Kraken(WritableImage image, Color targetColor) {
            this.img = image;
            this.targetColor = targetColor;
        }

        public void unleash(Point2D start, Color shade) {
            PixelReader reader = img.getPixelReader();
            PixelWriter writer = img.getPixelWriter();

            Stack<Point2D> stack = new Stack<>();
            stack.push(start);

            while (!stack.isEmpty()) {
                Point2D point = stack.pop();
                int x = (int) point.getX();
                int y = (int) point.getY();
                if (filled(reader, x, y)) {
                    continue;
                }

                writer.setColor(x, y, shade);

                push(stack, x - 1, y - 1);
                push(stack, x - 1, y    );
                push(stack, x - 1, y + 1);
                push(stack, x    , y + 1);
                push(stack, x + 1, y + 1);
                push(stack, x + 1, y    );
                push(stack, x + 1, y - 1);
                push(stack, x,     y - 1);
            }
        }

        private void push(Stack<Point2D> stack, int x, int y) {
            if (x < 0 || x > img.getWidth() ||
                y < 0 || y > img.getHeight()) {
                return;
            }

            stack.push(new Point2D(x, y));
        }

        private boolean filled(PixelReader reader, int x, int y) {
            Color color = reader.getColor(x, y);

            return !withinTolerance(color, targetColor, E);
        }

        private boolean withinTolerance(Color a, Color b, double epsilon) {
            return
                    withinTolerance(a.getRed(),   b.getRed(),   epsilon) &&
                    withinTolerance(a.getGreen(), b.getGreen(), epsilon) &&
                    withinTolerance(a.getBlue(),  b.getBlue(),  epsilon);
        }

        private boolean withinTolerance(double a, double b, double epsilon) {
            return Math.abs(a - b) < epsilon;
        }
    }
}

Responses to additional inquiries

Wouldn't the process of coloring each pixel be time-consuming?

Indeed, each pixel needs to be colored individually in this context. This granular control over pixels is essential for achieving the desired shading effect on images. In computer graphics, manipulating individual pixels is often necessary for precise visual rendering.

Is this method efficient in terms of coloring images?

The provided code demonstrates near-instantaneous coloring on the sample image provided. While it may consume some memory space, all flood fill algorithms require memory utilization. For enhanced efficiency, more advanced and complex algorithms can be employed from resources like the linked Wikipedia page, depending on specific requirements.

Alternative Strategy

If you possess stencil shapes for different regions, applying ColorAdjust effects stacked on stencils could present an alternative. Utilizing hardware-accelerated effects such as ColorAdjust offers optimized performance. However, this approach assumes prior knowledge of the stencil shapes for application, making it less universal than the flood fill technique.

Answer №2

Creating a circle shape with coordinates x, y, and radius r.
Creating a rectangle shape with coordinates x, y, width w, and height h.
Subtracting the rectangle from the circle to create a new region, essentially "cutting" the rectangle out of the circle.
Performing this subtraction process twice for each piece needed.
Setting the fill color of the new region to be blue.
Adding the shape to a node and defining its translation accordingly.

This method involves removing the overlapping area of the circle where the rectangle is positioned.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Adjusting the width of a kendo UI themed text field using CSS

Isn't it fascinating how you can adjust the width of a text box like this? @Html.TextBoxFor(m => m.LoginId, new { @class = "k-textbox", style="width:400px" }) However, I am seeking a more elegant solution. I attempted to implement this in a fres ...

Tips on how to postpone the loading of an image when utilizing a CSS animation on a different element

I'm currently working on a webpage where I have integrated CSS animations to move images around. When you click on these images, a larger version of the image along with a related paragraph is supposed to appear in its place. Initially, I had set up a ...

JQuery is facing difficulty in animating a div following the completion of a "forwards" css animation

Check out this example: http://jsfiddle.net/nxsv5dgw/ A div appears on the stage and a CSS animation is applied to it. However, when attempting to use JQuery to animate the same properties that were animated by CSS, it seems to no longer work properly. ...

What is the correct way to apply styles universally instead of using "*" as a selector?

With Nextron, I was able to successfully run my code, but upon opening the window, I noticed that the body tag had a margin of 8px. Although I managed to change this using the dev tools, I am unsure how to permanently apply this change in my code. When att ...

Position an element to the right inside its parent container with varying width in Internet Explorer 7 or earlier

I am trying to align a button to the right edge of a table inside a container-div that has no set width. The goal is to have the button float on the right side of the table, lining up with its right edge. While my current approach works in most browsers, i ...

CSS technique for arranging text in order?

My website has a unique layout where certain text appears differently on desktop and mobile devices. Specifically, I have a simple text that looks like this on desktop: Kolor : Niebieski Rozmiar : S/M However, I want it to appear like this on mobile: Ko ...

Attempting to relocate the final two links within my navigation div to the opposite side of the container div

Hey there! I've been trying to figure out how to move my 'Facebook' and 'Twitter' links to the right side of my navigation bar while keeping all the other links on the left. It's been quite a challenge so far! I've been ...

What is the best way to automatically adjust the size of an image to fit its

One of the challenges with the parent container is fitting an image inside it: .parent { position: relative; text-align: center; overflow: hidden; display: flex; align-items: center; align-content: center; justify-content: cente ...

What are the methods to retrieve the active profiles of a running Spring Boot application via the command line?

What is the best way to retrieve the active profile from a spring boot application while it is running using the command-line? I am familiar with using jcmd, but I have not been able to find any references to springboot properties through that method. Is ...

Exploring the origins of CSS through patch design

Want to learn how to create a background like this using CSS? Check out this link for inspiration! ...

Assign a class to a dynamically loaded element on a webpage

As I work on developing my website, I am facing an issue that I need help with. My header is stored in a separate HTML document and it looks like this: <div class="topnav" id="myTopnav"> <a href="Index.html" id=" ...

Characters from Font Awesome are invisible on my screen

I am struggling with the font awesome plugin as I am unable to view the characters. Below is my code snippet: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <l ...

Can you clarify the specific distinction between "ExpectedConditions.visibilityOfElementLocated" and "ExpectedConditions.presenceOfElementLocated"?

Greetings! As a novice in QA and Selenium, I apologize if my question seems basic. Can someone please explain the difference between the following code snippets: wait.until(ExpectedConditions.visibilityOfElementLocated (By.xpath("//a ...

Rearrange divs from left to right on mobile display

I need help creating a header bar with three elements as shown below https://i.sstatic.net/4njuk.png When viewed on mobile, I want the menu (toggle-icon) to shift left and the logo to be centered. I attempted using push and pull with no success. Is there ...

Is it possible to apply a styling to a table data cell based on the table header relationship

Let's say I have a table header with content like this... <th> <div class="text-left field-sorting " rel="local_inventory"> Local inventory </div> </th> <th> <div class="text-left field-sorting " rel="something el ...

Adding Font Awesome to my Angular 12 project within Visual Studio 2019

Seeking a no-frills guide for integrating Font Awesome (free version) into my Angular 12 application within Visual Studio 2019. After countless Google searches, I am bombarded with intricate methods. It's baffling why such complexity exists just to in ...

What's the best way to enable touch scrolling for items within a div container?

I am in the process of creating a code snippet that will allow users to scroll through items within a div, similar to a spinning wheel or slot machine. While I am aware of an existing solution for iPhone and iPod, I want to develop a simpler, more streamli ...

Steps to prepend a domain to file_get_contents function in PHP script

Recently, I enlisted the help of a PHP coder to make modifications to two files for me. The purpose was to allow users to link directly to a file converted from DOC to IMG on . Below you can find the edited code (highlighted by 'DrTech76'): get ...

pictures showcased in a grid that dance and sway

Hey everyone, I wanted to ask about images on a website that have a unique effect when you hover over them. On the site follow your feet website, there is a grid section of destinations and when you move your mouse over a destination, it suddenly expands a ...

Develop a straightforward user registration platform using solely HTML and MySql

Can a basic registration system be developed using only HTML, CSS, and MySql without the use of PHP? ...