如何仅将模糊应用于窗格内的矩形区域?

时间:2015-03-22 01:45:32

标签: java javafx javafx-8

让我们说我有一个StackPane作为背景BackgroundImage,另一个StackPane(或其他组件,如有必要)作为孩子。孩子只覆盖父StackPane的一部分。

我想知道如何将GaussianBlur仅应用于孩子所覆盖的区域,以便BackgroundImage在这个区域模糊不清。

调整父级的大小会改变子级的大小。获得一个能够及时调整大小的解决方案将是完美的。

1 个答案:

答案 0 :(得分:3)

如果您想手动执行此操作,可以使用snapshot功能创建快照图像,将其模糊并在每次调整父项大小时将其应用于子项。

但是,始终调用快照会导致性能下降。我建议你创建2个图像,一个正常,一个模糊,并显示模糊的viewport

这是一个更复杂的"例如,视口不足的圆圈。在这种情况下使用剪辑方法:

public class Lens extends Application {

    Image image = new Image( "http://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/800px-Siberischer_tiger_de_edit02.jpg");

    CirclePane circlePane;

    @Override
    public void start(Stage primaryStage) {

        ImageView normalImageView = new ImageView( image);
        ImageView blurredImageView = new ImageView( image);
        blurredImageView.setEffect(new GaussianBlur( 40));

        Group root = new Group();

        root.getChildren().addAll( normalImageView);

        Scene scene = new Scene( root, 1024, 768);

        primaryStage.setScene( scene);
        primaryStage.show();

        // pane with clipped area
        circlePane = new CirclePane( blurredImageView);
        makeDraggable( circlePane);

        root.getChildren().addAll( circlePane);

    }

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


    private class CirclePane extends Pane {

        ImageView blurredImageView;
        ImageView clippedView = new ImageView();

        public CirclePane( ImageView blurredImageView) {

            this.blurredImageView = blurredImageView;

            // new imageview
            update();

            getChildren().addAll( clippedView);

        }

        public void update() {

            // create circle
            Circle circle = new Circle( 200);
            circle.relocate( getLayoutX(), getLayoutY());

            // clip image by circle
            blurredImageView.setClip(circle);

            // non-clip area should be transparent
            SnapshotParameters parameters = new SnapshotParameters();
            parameters.setFill(Color.TRANSPARENT); 

            // new image from clipped image
            WritableImage wim = null;
            wim = blurredImageView.snapshot(parameters, wim);

            clippedView.setImage( wim);

        }

    }

    // make node draggable
    class DragContext { 
        double x;
        double y; 
    } 

    public void makeDraggable( Node node) {

        final DragContext dragDelta = new DragContext();

        node.setOnMousePressed(mouseEvent -> {

            dragDelta.x = node.getBoundsInParent().getMinX() - mouseEvent.getScreenX();
            dragDelta.y = node.getBoundsInParent().getMinY() - mouseEvent.getScreenY();

        });

        node.setOnMouseDragged(mouseEvent -> {

            node.relocate( mouseEvent.getScreenX() + dragDelta.x, mouseEvent.getScreenY() + dragDelta.y);
            circlePane.update();

        });

    }

}

只需点击圆圈并将其拖动即可。

enter image description here