【问题标题】:How to change background of an image in javafx如何在javafx中更改图像的背景
【发布时间】:2021-06-11 20:35:28
【问题描述】:

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

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

如果您需要了解背景的具体定义,可以说我想将 png 文件中每个白色像素的颜色更改为蓝色。 (不是在运行程序之前手动而是在代码内部)

【问题讨论】:

  • javafx 有一些image ops 你是如何显示你的图像的?
  • 使用像 GIMP 或 Photoshop 这样的绘图程序来使球周围的区域透明可能是最简单的。
  • 您确定您的图片有白色背景吗?许多图片都有透明背景。

标签: java javafx


【解决方案1】:

您可以从原始图像中获取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();
    }

}

【讨论】:

    【解决方案2】:

    这是另一种方式:

    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”代码的存在是为了让您了解每个像素的组件颜色,但会使代码变慢。如果此信息无关紧要,可以对打印的内容进行注释(这将使代码更快)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-13
      • 1970-01-01
      • 2016-03-02
      • 1970-01-01
      相关资源
      最近更新 更多