Обрезка изображения ImageView в контейнере Group — Javafx

У меня проблема с группировкой, javafx. Моя программа состоит в том, чтобы нарисовать Rectangle на ImageView для обрезки Image. Координаты получаются при нажатии и отпускании мыши. Когда я помещаю группу в макет GridPane, прямоугольник не рисуется в правильном положении.

Моя программа

package application;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;


public class Main extends Application {
     double x1,y1,x2,y2;
     int ulx,uly,w,h;
     String filename;
     @Override
     public void start(Stage primaryStage) {
         try {
            GridPane grid = new GridPane(); 
           //grid.setAlignment(Pos.TOP_LEFT); 
            grid.setHgap(20); 
            grid.setVgap(10); 
            grid.setPadding(new Insets(0, 10, 10, 10));

            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            double width = screenSize.getWidth() - 100;
            double height = screenSize.getHeight()- 100;
            double panelWidth = (width)/2 - 50;
            double panelHeight = (9*panelWidth)/16;
            double panelX = width-panelWidth-50-20;
            double panelY = 0.0;

             Rectangle rectangle = new Rectangle();
             BorderPane root = new BorderPane();
             Scene scene = new Scene(grid,width,height);
             scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());

             File imagePath1 = new File("plugins\\image\\car.jpg");
             Image image1 = new Image(imagePath1.toURI().toString());
             ImageView imageView1 = new ImageView();
             imageView1.setId("imageView");
             imageView1.setImage(image1);
             imageView1.setFitWidth(panelWidth);
             imageView1.setFitHeight(panelHeight);
             imageView1.setPreserveRatio(false);
             imageView1.setSmooth(true);
             imageView1.setCache(true);


             File imagePath = new File("plugins\\image\\car.jpg");
             Image image = new Image(imagePath.toURI().toString());
             ImageView imageView = new ImageView();
             imageView.setId("imageView");        
             imageView.setImage(image);
             imageView.setFitWidth(panelWidth);
             imageView.setFitHeight(panelHeight);
             imageView.setPreserveRatio(false);
             imageView.setSmooth(true);
             imageView.setCache(true);

             imageView.setOnMousePressed(new EventHandler <MouseEvent>()
                {
                    public void handle(MouseEvent event)
                    {
                        imageView.setMouseTransparent(true);
                        x1 = event.getSceneX() ;
                        y1 = event.getSceneY();
                        System.out.println(x1+" "+y1);
                        event.setDragDetect(true);
                    }
                });

             imageView.setOnMouseDragged(new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        // TODO Auto-generated method stub
                        double tx1=x1,ty1=y1,tx2=0,ty2=0;
                        double tempX=0,tempY=0;

                        if(event.getSceneX()<panelX || event.getSceneX()>(panelX+panelWidth) || event.getSceneY()<0 || event.getSceneY()>(panelY+panelHeight)){
                            if(event.getSceneX()<panelX){
                                tempX = 0;
                                tempY = event.getSceneY();
                            }
                            else if(event.getSceneX()>(panelX+panelWidth)){
                                tempX = panelX+panelWidth;
                                tempY = event.getSceneY();
                            }
                            if(event.getSceneY()<panelY){
                                tempX = event.getSceneX();
                                tempY = 0;
                            }
                            else if(event.getSceneY()>(panelY+panelHeight)){
                                tempX = event.getSceneX();
                                tempY = panelY+panelHeight;
                            }
                        }
                        else{
                            tempX = event.getSceneX();
                            tempY = event.getSceneY();
                        }

                        if(tempX<tx1 && tempY<ty1){
                            tx2 = tx1;
                            tx1 = tempX;
                            ty2 = ty1;
                            ty1 = tempY;                            
                        }
                        else if(tempX<tx1 && tempY>ty1){
                            tx2 = tx1;
                            tx1 = tempX;
                            ty2 = tempY;
                        }
                        else if(tempX>tx1 && tempY<ty1){
                            tx2 = tempX;
                            ty2 = ty1;
                            ty1 = tempY;
                        }
                        else if(tempX>tx1 && tempY>ty1){
                            tx2 = tempX;
                            ty2 = tempY;    
                        }

                        ulx = (int)tx1;
                        uly = (int)ty1;
                        w =(int) (tx2-tx1);
                        h = (int)(ty2-ty1);
                        rectangle.setX(ulx);
                        rectangle.setY(uly);
                        rectangle.setWidth(w);
                        rectangle.setHeight(h);
                        rectangle.setFill(Color.TRANSPARENT);
                        rectangle.setStroke(Color.WHITE);
                        rectangle.setStrokeWidth(2);
                        rectangle.getStrokeDashArray().addAll(7d, 5d);  
                    }
                });

             imageView.setOnMouseReleased(new EventHandler <MouseEvent>()
                {
                    public void handle(MouseEvent event)
                    {
                        imageView.setMouseTransparent(false);
                        if(event.getSceneX()<x1){
                            x2 = x1;
                            x1 =event.getSceneX();
                        }
                        else{
                            x2 = event.getSceneX();
                        }
                        if(event.getSceneY()<y1){
                            y2 = y1;
                            y1 =event.getSceneY();
                        }
                        else{
                            y2 = event.getSceneY();
                        }

                        ulx = (int)x1;
                        uly = (int)y1;
                        w =(int) (x2-x1);
                        h = (int)(y2-y1);
                        System.out.println(x1+" "+y1+" "+x2+" "+y2+" "+w+" "+h);
                        filename = String.valueOf(x1)+"_"+String.valueOf(y1)+"_"+String.valueOf(w)+"_"+String.valueOf(h);
                        rectangle.setX(ulx);
                        rectangle.setY(uly);
                        rectangle.setWidth(w);
                        rectangle.setHeight(h);
                        rectangle.setFill(Color.TRANSPARENT);
                        rectangle.setStroke(Color.WHITE);
                        rectangle.setStrokeWidth(2);
                        rectangle.getStrokeDashArray().addAll(7d, 5d);
                    }
                });

             Group group = new Group(imageView, rectangle);

             HBox option = new HBox();
             Button save = new Button("SAVE");
             save.setOnAction(new EventHandler<ActionEvent>() {
                    public void handle(ActionEvent e){
                        double x = x1-panelX;
                        double y = y1-panelY;
                        WritableImage image = imageView.snapshot(new SnapshotParameters(), null);
                        PixelReader reader = image.getPixelReader();
                        WritableImage newImage = new WritableImage(reader, (int)(x), (int)(y), w, h);
                            // TODO: probably use a file chooser here
                        filename = String.valueOf(x)+"_"+String.valueOf(y)+"_"+String.valueOf(w)+"_"+String.valueOf(h);
                            File file = new File(filename+".png");
                            try {
                                ImageIO.write(SwingFXUtils.fromFXImage(newImage, null), "png", file);
                            } catch (IOException ec) {
                                // TODO: handle exception here
                            }
                    }
                });

             option.getChildren().add(save);

             root.setLeft(group);

             grid.add(imageView1, 0, 0);
             grid.add(group, 1, 0);
             grid.add(option, 1, 1);


             primaryStage.setScene(scene);
             primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}

Мой выходной снимок экрана

Мой выходной скриншот

Но прямоугольник должен быть в imageView


person Naveen Andrew    schedule 01.02.2017    source источник


Ответы (1)


ИСПОЛЬЗОВАНИЕ

  • щелкните правой кнопкой мыши, чтобы удалить линии обрезки
  • двойной щелчок, чтобы вырезать изображение

введите здесь описание изображения

введите здесь описание изображения

вы видите снимки экрана? некоторые из ваших расчетов не нужны, запустите все в MouseEvent, он сделает всю тяжелую работу за вас.

забудьте GridPane и используйте абсолютные координаты при обрезке, GridPane изменит позиции, потому что он вынужден подчиняться правилам компоновки в onLayout() используйте кого-то вроде Pane и заверните в HBox, затем поместите их в ScrollPane, вот и все, легко и приятно как она...

Изображения есть в сети, моя сестра очень популярна :)

код

 public class Main extends Application {

final Rectangle rectBound = new Rectangle(0, 0);
Random ran = new Random();

 @Override
 public void start(Stage primaryStage) {
 try {
     rectBound.setFill(Color.TRANSPARENT);
     rectBound.setStroke(Color.GOLD);
     ScrollPane scp = new ScrollPane();
     HBox root = new HBox(15);
     scp.setContent(root);
     //root.setOrientation(Orientation.HORIZONTAL);

     Pane imageViewParent = new Pane();
     imageViewParent.setStyle("-fx-border-color: black; -fx-border-width: 2;");

     ImageView imageView1 = new ImageView(new Image(getUrl(),true));
     imageView1.setLayoutX(0.0);imageView1.setLayoutY(0.0);
     imageViewParent.getChildren().add(imageView1);

     ///////////////////////////////////////////////
     imageViewParent.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
        @Override
            public void handle(MouseEvent event) {

                if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
                    if (rectBound.getParent() == null) {
                        rectBound.setWidth(0.0); rectBound.setHeight(0.0);
                        rectBound.setLayoutX(event.getX()); rectBound.setLayoutY(event.getY()); // setX or setY
                        imageViewParent.getChildren().add(rectBound);
                    }
                } else if (event.getEventType() == MouseEvent.MOUSE_RELEASED) {

                } else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
                    rectBound.setWidth(event.getX() - rectBound.getLayoutX());
                    rectBound.setHeight(event.getY() - rectBound.getLayoutY());
                } else if (event.getEventType() == MouseEvent.MOUSE_CLICKED
                        && event.getButton() == MouseButton.SECONDARY) {
                    if (rectBound.getParent() != null) {
                        imageViewParent.getChildren().remove(rectBound);
                    }
                } else if (event.getEventType() == MouseEvent.MOUSE_CLICKED
                        && event.getButton() == MouseButton.PRIMARY && event.getClickCount() > 1) {
                    //////////////// i crop here //////////////
                    PixelReader reader = imageView1.getImage().getPixelReader();
                    WritableImage newImage = new WritableImage(reader, (int) rectBound.getLayoutX(),
                            (int) rectBound.getLayoutY(),
                            (int) rectBound.getWidth(),
                            (int) rectBound.getHeight());

                    root.getChildren().add(new ImageView(newImage));
                }

            }
    });
     //////////////////////////////////////////////
     root.getChildren().add(imageViewParent);

     Scene scene = new Scene(scp,900,650);
     primaryStage.setScene(scene);
     primaryStage.show();
    } catch(Exception e) {
        e.printStackTrace();
    }
}

private String getUrl() {
    switch (ran.nextInt(4)) {
    case 1:
        return "http://6544-presscdn-0-22.pagely.netdna-cdn.com/wp-content/uploads/2013/06/Juliet-Ibrahim2.jpg";

    case 4:
        return "http://6544-presscdn-0-22.pagely.netdna-cdn.com/wp-content/uploads/2016/02/Nadia-Buari.jpg";

    case 2:
        return "http://www.eonlineghana.com/wp-content/uploads/2016/03/1.jpg";

    case 3:
        return "http://fashionpoliceng.com/wp-content/uploads/2015/08/Juliet-Ibrahim-527x600.jpg";

    default:
        return "http://6544-presscdn-0-22.pagely.netdna-cdn.com/wp-content/uploads/2014/04/Juliet-Ibrahim-Foundation-1.jpg";
    }
}

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

Надеюсь, поможет

person Elltz    schedule 06.02.2017