如何使用JavaFx删除图像的颜色(使背景透明)?

时间:2016-03-10 01:21:06

标签: java image javafx background transparency

我的图片已加载ImageImageView

我想制作图像的背景,白色,透明以与背景匹配。

1 个答案:

答案 0 :(得分:5)

使用Reduce number of colors and get color of a single pixel中使用的PixelWriter和WritableImage查看重采样技术。您可以使用相同的技术并将白色像素(rgb 255,255,255)更改为透明(rgba 0,0,0,0)。

在应用程序中使用图像之前,您也可以执行此操作in an image editing program

以下是使用Easily Remove White Or Black Backgrounds with Blending Sliders in Photoshop中的图片的示例。

简单的重采样实现如下所示:

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);
    }
}

当TOLERANCE_THRESHOLD设置为0xFF时,只有纯白色像素会变为透明,您将获得如下图像。角色周围的白色部分是因为某些背景不是完全白色而是略带灰色,因此重采样不会修改它的alpha值。

low tolerance

将TOLERANCE_THRESHOLD减小到0xCF会产生如下图像,其中一些浅灰色背景变为透明。请注意,这个结果并不完美,因为角色周围仍然有一个别名的灰色轮廓,角色的白色头盔变得透明。您可以将算法修改为更加智能,并且更像是图像绘制应用程序的lasso tool,但这可能会变得棘手,并且在没有人员参与的情况下仍然可能会出错。如果上面列出的简单程序化程序不足以按照您的意愿正确重新采样图像,那么最好在图像编辑程序中提前设置透明度(在任何情况下,这都是我建议的大多数情况)。

high tolerance