Javafx图像与不同的角落

 2023-02-16    395  

问题描述

如可以剪切imageViews以实现角落舍入(CSS无法实现图像视图的角舍入).
但是,我试图拥有不同的角度半径,非常类似于这片CSS的描述:

.background {
    -fx-background-radius: 64 0 16 0;
}

我希望图像的外观(图像=黑色区域)几乎是:
在这里输入图像说明

我目前面临的问题是,例如,不可能用VBox剪辑imageViews.但是,我可以用Rectangle剪辑imageView,但这又一次没有给我带来不同的拐角半径的可能性.

我如何达到与上述CSS代码相同的效果(当然哪个与ImageView不起作用)并且具有不同的角度?

推荐答案

带路径的剪辑图像

剪辑imageView javafx

在这种方法中,ImageView用Path剪辑.该路径将适应每个图像视图的fitwidth和传递到getClip方法的fitheight值.第二个和第三个参数是根据fitheight计算顶部和底部角半径的值.

getClip方法将绘制这样的路径:

 path

这是一个单一类Javafx应用程序,您可以尝试

app.java

public class App extends Application {

    @Override
    public void start(Stage stage) {

        ImageView imageView = new ImageView("https://ioppublishing.org/wp-content/uploads/2017/03/cat-web-cc0.jpg");
        imageView.setFitHeight(300);
        imageView.setFitWidth(300);
        imageView.setClip(getClip(imageView, 0.1,0.3));

        ImageView imageView1 = new ImageView("https://ioppublishing.org/wp-content/uploads/2017/03/cat-web-cc0.jpg");
        imageView1.setFitHeight(400);
        imageView1.setFitWidth(400);
        imageView1.setClip(getClip(imageView1, 0.2,0.3));

        VBox vBox = new VBox(imageView, imageView1);
        vBox.setSpacing(20);
        vBox.setPadding(new Insets(20));
        vBox.setAlignment(Pos.CENTER);
        vBox.setFillWidth(true);
        var scene = new Scene(new StackPane(vBox), 1024, 800);

        stage.setScene(scene);
        stage.setTitle("clipping with path");
        stage.show();

    }

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

    private Node getClip(ImageView imageView, double radiusTop,double radiusBot) {
        Path clip;

        double height = imageView.getFitHeight();
        double width = imageView.getFitWidth();
        double radius1 = height * radiusTop;
        double radius2 = height * radiusBot;
        clip = new Path(new MoveTo(0, radius1), new ArcTo(radius1, radius1, 0, radius1, 0, false, true),
                new HLineTo(width),
                new VLineTo(height - radius2),
                new ArcTo(radius2, radius2, 0, width - radius2, height, false, true),
                new HLineTo(0));

        clip.setFill(Color.ALICEBLUE);

        return clip;

    }

}

所有角落的更新
剪辑All Corners Javafx

app.java

public class App extends Application {

    @Override
    public void start(Stage stage) {

        ImageView imageView = new ImageView("https://ioppublishing.org/wp-content/uploads/2017/03/cat-web-cc0.jpg");
        imageView.setFitHeight(300);
        imageView.setFitWidth(300);
        imageView.setClip(getClip(imageView, 0.3, 0.1, 0.2, 0.1));

        ImageView imageView1 = new ImageView("https://ioppublishing.org/wp-content/uploads/2017/03/cat-web-cc0.jpg");
        imageView1.setFitHeight(400);
        imageView1.setFitWidth(400);
        imageView1.setClip(getClip(imageView1, 0.3, 0.2, 0.1, 0.2));

        VBox vBox = new VBox(imageView, imageView1);
        vBox.setSpacing(20);
        vBox.setPadding(new Insets(20));
        vBox.setAlignment(Pos.CENTER);
        vBox.setFillWidth(true);
        var scene = new Scene(new StackPane(vBox), 1024, 800);

        stage.setScene(scene);
        stage.setTitle("clipping with path");
        stage.show();

    }

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

    private Node getClip(ImageView imageView, double topLeft, double topRight, double bottomLeft, double bottomRight) {
        Path clip;

        double height = imageView.getFitHeight();
        double width = imageView.getFitWidth();
        double radius1 = height * topLeft;
        double radius2 = height * topRight;
        double radius3 = height * bottomLeft;
        double radius4 = height * bottomRight;

        clip = new Path(new MoveTo(0, radius1),
                new ArcTo(radius1, radius1, 0, radius1, 0, false, true),
                new HLineTo(width - radius2),
                new ArcTo(radius2, radius2, 0, width, radius2, false, true),
                new VLineTo(height - radius4),
                new ArcTo(radius4, radius4, 0, width - radius4, height, false, true),
                new HLineTo(radius3),
                new ArcTo(radius3, radius3, 0, 0, height - radius3, false, true));

        clip.setFill(Color.ALICEBLUE);

        return clip;

    }

}

其他推荐答案

一种可能的解决方案是添加几种形状,并使用这些添加的形状夹紧图像视图.下面的UTIL类是这样做的.
为了实现CSS代码-fx-background-radius: 64 0 16 0的效果(如果适用于ImageViews),您会致电:

ImageView rounded = ImageUtils.round(image, 64, 0, 16, 0);

UTIL类工作的方式是,它用相应的半径为每个角生成四个不同的矩形,并使这四个矩形在中心中重叠:

在此处输入图像说明

然后将它们放在一个组中,并用该组剪辑图像视图:

public class ImageUtils {

    public static ImageView round(Image image,
                              double topLeft,
                              double topRight,
                              double bottomRight,
                              double bottomLeft) {
        topLeft *= 2;
        topRight *= 2;
        bottomRight *= 2;
        bottomLeft *= 2;

        double width = image.getWidth();
        double height = image.getHeight();

        double topEdgeHalf = (width - topLeft - topRight) / 2;
        double rightEdgeHalf = (height - topRight - bottomRight) / 2;
        double bottomEdgeHalf = (width - bottomLeft - bottomRight) / 2;
        double leftEdgeHalf = (height - topLeft - bottomLeft) / 2;

        double topLeftWidth = topEdgeHalf + 2 * topLeft;
        double topLeftHeight = leftEdgeHalf + 2 * topLeft;
        double topLeftX = 0;
        double topLeftY = 0;

        double topRightWidth = topEdgeHalf + 2 * topRight;
        double topRightHeight = rightEdgeHalf + 2 * topRight;
        double topRightX = width - topRightWidth;
        double topRightY = 0;

        double bottomRightWidth = bottomEdgeHalf + 2 * bottomRight;
        double bottomRightHeight = rightEdgeHalf + 2 * bottomRight;
        double bottomRightX = width - bottomRightWidth;
        double bottomRightY = height - bottomRightHeight;

        double bottomLeftWidth = bottomEdgeHalf + 2 * bottomLeft;
        double bottomLeftHeight = leftEdgeHalf + 2 * bottomLeft;
        double bottomLeftX = 0;
        double bottomLeftY = height - bottomLeftHeight;

        Rectangle topLeftRect = new Rectangle(topLeftX, topLeftY, topLeftWidth, topLeftHeight);
        Rectangle topRightRect = new Rectangle(topRightX, topRightY, topRightWidth, topRightHeight);
        Rectangle bottomRightRect = new Rectangle(bottomRightX, bottomRightY, bottomRightWidth, bottomRightHeight);
        Rectangle bottomLeftRect = new Rectangle(bottomLeftX, bottomLeftY, bottomLeftWidth, bottomLeftHeight);

        topLeftRect.setArcWidth(topLeft);
        topLeftRect.setArcHeight(topLeft);
        topRightRect.setArcWidth(topRight);
        topRightRect.setArcHeight(topRight);
        bottomRightRect.setArcWidth(bottomRight);
        bottomRightRect.setArcHeight(bottomRight);
        bottomLeftRect.setArcWidth(bottomLeft);
        bottomLeftRect.setArcHeight(bottomLeft);

        Group clipGroup = new Group(
                topLeftRect,
                topRightRect,
                bottomRightRect,
                bottomLeftRect
        );

        ImageView clipped = new ImageView(image);
        clipped.setClip(clipGroup);
        return clipped;
    }
}

以上所述是小编给大家介绍的Javafx图像与不同的角落,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/33898.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。