如何在javafx中更改图像的背景



我有一个javafx应用程序,我的窗格中有一个矩形,我使用rectangle.setFill()用图像填充矩形。现在假设图像是一个圆形的红色球,但我们都知道png文件是一个矩形。(有宽度和高度(,所以这个png文件的一些部分是白色的。(红圈外(。我想知道是否可以用另一种颜色来改变图像的白色部分,比如蓝色。

所以我不想为我的anchorpane设置背景色,如果我这样做了,在执行rectangle.setFill()行之后,它会用我在命令中放入的图像填充矩形,而不考虑anchorpanee的背景色。我想改变背景的颜色;png文件"我在代码中放入了rectangle.setFill()

如果你需要知道背景的具体定义,比如说我想把png文件中每个白色像素的颜色都改为蓝色。(在运行程序之前不是手动操作,而是在代码内部(

您可以从原始图像中获取PixelReader,用于查询单个像素的颜色。

然后,您可以创建一个PixelBuffer并将像素复制到其中,调整任何需要调整的像素。

然后从PixelBuffer创建一个WritableImage。您甚至可以动态调整像素数据,在缓冲区上调用updateBuffer以确保图像更新。

这里有一个例子,你可以选择一种颜色来代替白色背景:

import java.nio.IntBuffer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ColorPicker;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelBuffer;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.PixelReader;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class App extends Application {
@Override
public void start(Stage stage) {
Image originalImage = createImage();
ImageView orig =  new ImageView(originalImage);

ColorPicker colorPicker = new ColorPicker(Color.BLUE);

int width = (int) originalImage.getWidth();
int height = (int) originalImage.getHeight();

int[] pixels = new int[width * height];
PixelBuffer<IntBuffer> pixelBuffer = new PixelBuffer<IntBuffer>(width, height, IntBuffer.wrap(pixels), PixelFormat.getIntArgbPreInstance());
adjustImage(originalImage, colorPicker.getValue(), pixelBuffer, pixels);

ImageView adjusted = new ImageView(new WritableImage(pixelBuffer));

HBox images = new HBox(5, orig, adjusted);

colorPicker.valueProperty().addListener((obs, oldColor, newColor) -> adjustImage(originalImage, newColor, pixelBuffer, pixels));

HBox controls = new HBox(5, colorPicker);

BorderPane root = new BorderPane(images);
root.setTop(controls);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();

}

private void adjustImage(Image original, Color newColor, PixelBuffer<IntBuffer> buffer, int[] pixels) {

int alpha = (int)(newColor.getOpacity() * 255) ;
int r = (int)(newColor.getRed() * 255);
int g = (int)(newColor.getGreen() * 255);
int b = (int)(newColor.getBlue() * 255);

int replacement = alpha << 24 | r << 16 | g << 8 | b ;

int width = (int)original.getWidth() ;
int height = (int)original.getHeight();
PixelReader pixelReader = original.getPixelReader() ;
for (int y = 0 ; y < height ; y++) {
for (int x = 0 ; x < width ; x++) {
int argb = pixelReader.getArgb(x, y);
if (argb == 0xFFFFFFFF) {
pixels[x+y*width] = replacement ;
} else {
pixels[x+y*width] = argb ;
}
}
}
buffer.updateBuffer(buff -> null);
}

private Image createImage() {

// In real life here you can just read an image from a resource in the normal way
// This just creates an image on the fly to make the example stand alone

int width = 400 ;
int height = 400 ;
int[] pixels = new int[width*height];
for (int y = 0 ; y < height ; y++) {
for (int x = 0 ; x < width ; x++) {
if ((x-200)*(x-200) + (y-200)*(y-200) < 40000) {
pixels[x+y*width] = 0xffff0000 ;
} else {
pixels[x+y*width] = 0xffffffff ;
}
}
}
return new WritableImage(new PixelBuffer<IntBuffer>(width, height, IntBuffer.wrap(pixels), PixelFormat.getIntArgbPreInstance()));
}
public static void main(String[] args) {
launch();
}
}

这里有另一种方法:

package application;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.paint.Color;
import javafx.scene.image.WritableImage;

public class ImageOpsTest extends Application {

@Override
public void start(Stage primaryStage) {

// Create Image and ImageView objects
Image image = new Image("file:///home/paradigma/Imagens/photo.png");


ImageView imageView = new ImageView();
imageView.setImage(image);

// Obtain PixelReader
PixelReader pixelReader = image.getPixelReader();
System.out.println("Image Width: "+image.getWidth());
System.out.println("Image Height: "+image.getHeight());
System.out.println("Pixel Format: "+pixelReader.getPixelFormat());

// Create WritableImage
WritableImage wImage = new WritableImage(
(int)image.getWidth(),
(int)image.getHeight());
PixelWriter pixelWriter = wImage.getPixelWriter();

// Determine the color of each pixel in a specified row
for(int readY=0;readY<image.getHeight();readY++){
for(int readX=0; readX<image.getWidth();readX++){
Color color = pixelReader.getColor(readX,readY);
System.out.println("nPixel color at coordinates ("+
readX+","+readY+") "
+color.toString());
System.out.println("R = "+color.getRed());
System.out.println("G = "+color.getGreen());
System.out.println("B = "+color.getBlue());
System.out.println("Opacity = "+color.getOpacity());
System.out.println("Saturation = "+color.getSaturation());

if (color.equals(Color.WHITE)) color = color.BLUE;
pixelWriter.setColor(readX,readY,color);
}
}

// Display image on screen
imageView.setImage(wImage);
StackPane root = new StackPane();
root.getChildren().add(imageView);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Image Write Test");
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {
launch(args);
}
}

";System.out.println";代码的存在是为了给出每个像素的成分颜色的概念,然而,会使代码变慢。如果这些信息不相关,则可以对打印内容进行注释(这将使代码更快(。

最新更新