gpt4 book ai didi

java - javafx 中是否有任意形状的 "fill"函数?

转载 作者:行者123 更新时间:2023-11-29 07:02:25 25 4
gpt4 key购买 nike

我需要知道如何使用 JavaFX 为以下图像 (PNG) 着色。此图像当前包含在 JavaFX 的 ImageView 中:

image with different sections

我想给区域 1 涂上蓝色,第二个涂上红色,最后两个涂上紫色。我如何在 JavaFX 中执行此操作?难道没有像Windows Paint 中那样的某种功能吗? (你知道,用边界之间的颜色填充特定区域的绘画桶)。

最佳答案

建议的方法

您可以使用 flood fill算法。

filled

示例代码

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 updateable = new WritableImage(
original.getPixelReader(),
(int) original.getWidth(),
(int) original.getHeight()
);

Kraken kraken = new Kraken(updateable, 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(updateable);

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

class Kraken {
private final WritableImage image;
private final Color colorToFill;

// tolerance for color matching (on a scale of 0 to 1);
private final double E = 0.3;

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

public void unleash(Point2D start, Color color) {
PixelReader reader = image.getPixelReader();
PixelWriter writer = image.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, color);

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 > image.getWidth() ||
y < 0 || y > image.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, colorToFill, 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;
}
}
}

其他问题的答案

But wouldn't the image be colored pixel by pixel?

是的,这就是重点,您需要对像素进行着色。带有位图显示的计算机图形学中的一切最终都归结为着色像素。

Is this an efficient way in coloring?

它在您提供的示例图片上是即时的(据我所知)。在空间方面它占用了一些内存,但所有这些算法都会使用内存。我提供的示例代码不是可以设计的最有效的洪水填充着色算法(时间或空间方面)。我链接的维基百科页面有替代的更有效(也更复杂)的算法,您可以如果需要应用。

替代方法

如果每个区域都有切出的模板形状,您可以堆叠模板并应用 ColorAdjust对他们的影响(例如:How to change color of image in JavaFX)。 ColorAdjust(可能)是一种硬件加速效果。这种替代方法不是通用方法,因为它需要您了解模板形状。

关于java - javafx 中是否有任意形状的 "fill"函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23983465/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com