How to delete a color of an image with JavaFx (mak

2019-06-08 11:27发布

I have an image loaded with Image and ImageView.

I want to make the background of the image, which is white, transparent to match with the background.

1条回答
时光不老,我们不散
2楼-- · 2019-06-08 11:55

See the resampling technique using a PixelWriter and WritableImage used in Reduce number of colors and get color of a single pixel. You can use the same technique and change the white pixels (rgb 255,255,255) to transparent (rgba 0,0,0,0).

You could also do this in an image editing program before you use the image in your application.

Here is a sample using the image from Easily Remove White Or Black Backgrounds with Blending Sliders in Photoshop.

A simple resampling implementation is shown below:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class XRayVision extends Application {
    private static final int TOLERANCE_THRESHOLD = 0xFF;
    private static final String BACKGROUND_IMAGE_LOC = 
            "http://imgs.abduzeedo.com/files/articles/20_beautiful_landscape_wallpapers/landscape-wallpaper-1.jpg";
    private static final String ORIGINAL_IMAGE_LOC = 
            "http://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2011/01/toy.jpg";

    private Image makeTransparent(Image inputImage) {
        int W = (int) inputImage.getWidth();
        int H = (int) inputImage.getHeight();
        WritableImage outputImage = new WritableImage(W, H);
        PixelReader reader = inputImage.getPixelReader();
        PixelWriter writer = outputImage.getPixelWriter();
        for (int y = 0; y < H; y++) {
            for (int x = 0; x < W; x++) {
                int argb = reader.getArgb(x, y);

                int r = (argb >> 16) & 0xFF;
                int g = (argb >> 8) & 0xFF;
                int b = argb & 0xFF;

                if (r >= TOLERANCE_THRESHOLD 
                        && g >= TOLERANCE_THRESHOLD 
                        && b >= TOLERANCE_THRESHOLD) {
                    argb &= 0x00FFFFFF;
                }

                writer.setArgb(x, y, argb);
            }
        }

        return outputImage;
    }

    @Override
    public void start(final Stage stage) throws Exception {
        final Image backgroundImage = new Image(BACKGROUND_IMAGE_LOC);
        final ImageView backgroundImageView = new ImageView(backgroundImage);
        final Image originalImage = new Image(ORIGINAL_IMAGE_LOC);
        final ImageView originalImageView = new ImageView(originalImage);
        final Image resampledImage = makeTransparent(originalImage);
        final ImageView resampledImageView = new ImageView(resampledImage);

        final HBox images = new HBox(originalImageView, resampledImageView);
        stage.getIcons().add(originalImage);

        final StackPane layout = new StackPane(backgroundImageView, images);
        stage.setScene(new Scene(layout));
        stage.show();
    }

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

When the TOLERANCE_THRESHOLD is set to 0xFF, only pure white pixels will be changed to transparent, and you get the image as below. The white portion around the character is because some of the background is not exactly white but is slightly gray, so the resampling doesn't modify it's alpha value.

low tolerance

Decreasing the TOLERANCE_THRESHOLD to 0xCF produces an image like below, where some of the light gray background becomes transparent. Note that this outcome is not perfect as it there is still an aliased gray outline around the character and the white helmet of the character becomes transparent. You could modify the algorithm to be a bit more intelligent and act more like the lasso tool of an image drawing application, however that would probably get tricky and may still make mistakes without a human involved. If the simplistic programmatic routine below outlined above is not enough to correctly resample your image as you like, you will be best off setting up the transparency ahead of time in an image editing program (which is what I would recommend for most cases in any case).

high tolerance

查看更多
登录 后发表回答