非常感谢b站up主Aimls的课程
https://space.bilibili.com/5096022?spm_id_from=333.788.b_765f7570696e666f.1
需求:
使用fx做出UI界面,UI界面上有一个截图按钮,当我点击按钮的时候,能够像QQ截图那样,能够拉出一个矩形,然后点击完成,即可截图成功,并且图片可以在这个UI界面的空白区域预览,并且缓存到本地磁盘下。
截图功能实现思路:
点击截图按钮,弹出可以覆盖整个屏幕的透明面板。在这个面板上,可以绘制一个矩形,并且矩形绘制出来后,获取这个矩形的坐标参数和长宽参数,同时为了提高像素,关闭这个面板,通过矩形的参数,然后截图。
实验所需包:
1 import java.awt.Rectangle; 2 import java.awt.Robot; 3 import java.awt.image.BufferedImage; 4 import java.io.File; 5 import javax.imageio.ImageIO; 6 import javafx.application.Application; 7 import javafx.embed.swing.SwingFXUtils; 8 import javafx.event.ActionEvent; 9 import javafx.event.EventHandler; 10 import javafx.geometry.Pos; 11 import javafx.scene.Scene; 12 import javafx.scene.control.Button; 13 import javafx.scene.control.Label; 14 import javafx.scene.image.ImageView; 15 import javafx.scene.image.WritableImage; 16 import javafx.scene.input.Clipboard; 17 import javafx.scene.input.ClipboardContent; 18 import javafx.scene.input.KeyCode; 19 import javafx.scene.input.KeyCombination; 20 import javafx.scene.input.KeyEvent; 21 import javafx.scene.input.Mnemonic; 22 import javafx.scene.input.MouseDragEvent; 23 import javafx.scene.input.MouseEvent; 24 import javafx.scene.layout.AnchorPane; 25 import javafx.scene.layout.Border; 26 import javafx.scene.layout.BorderStroke; 27 import javafx.scene.layout.BorderStrokeStyle; 28 import javafx.scene.layout.BorderWidths; 29 import javafx.scene.layout.HBox; 30 import javafx.scene.paint.Paint; 31 import javafx.stage.Stage; 32 import javafx.stage.StageStyle;
核心代码如下:
1 public class jietu extends Application { 2 static ImageView iv; 3 static Button btn_jietu; 4 static Stage primary, stage; 5 static double sceneX_start; 6 static double sceneY_start; 7 static double sceneX_end; 8 static double sceneY_end; 9 static HBox hbox; 10 public static void main(String[] args) { 11 /*启动程序*/ 12 Application.launch(args); 13 } 14 public void start(Stage stage) throws Exception { 15 primary = stage; 16 AnchorPane root = new AnchorPane(); 17 btn_jietu = new Button("截图"); 18 iv = new ImageView(); 19 iv.setFitWidth(400); 20 iv.setPreserveRatio(true); 21 22 root.getChildren().addAll(btn_jietu, iv); 23 AnchorPane.setTopAnchor(btn_jietu, 50.0); 24 AnchorPane.setLeftAnchor(btn_jietu, 50.0); 25 26 AnchorPane.setTopAnchor(iv, 100.0); 27 AnchorPane.setLeftAnchor(iv, 50.0); 28 Scene scene = new Scene(root); 29 stage.setHeight(600); 30 stage.setWidth(800); 31 stage.setScene(scene); 32 stage.show(); 33 34 btn_jietu.setOnAction(new EventHandler<ActionEvent>() { 35 @Override 36 public void handle(ActionEvent event) { 37 // TODO 自动生成的方法存根 38 show(); 39 } 40 41 }); 42 /*设置快捷键*/ 43 KeyCombination key = KeyCombination.valueOf("ctrl+alt+a"); 44 Mnemonic mc = new Mnemonic(btn_jietu, key); 45 scene.addMnemonic(mc); 46 47 } 48 49 public void show() { 50 primary.setIconified(true);// 隐藏窗口 51 stage = new Stage(); 52 AnchorPane an = new AnchorPane(); 53 an.setStyle("-fx-background-color:#B5B5B522"); 54 Scene scene = new Scene(an); 55 scene.setFill(Paint.valueOf("#ffffff00")); 56 57 stage.setFullScreenExitHint("");// 设置空字符串 58 stage.setScene(scene); 59 stage.setFullScreen(true);// 全屏 60 stage.initStyle(StageStyle.TRANSPARENT);// 透明 61 stage.show(); 62 63 drag(an);//调用矩形拖拉 64 65 scene.setOnKeyPressed(new EventHandler<KeyEvent>() { 66 @Override 67 public void handle(KeyEvent event) { 68 // TODO 自动生成的方法存根 69 if (event.getCode() == KeyCode.ESCAPE) { 70 stage.close(); 71 primary.setIconified(false); 72 } 73 } 74 75 }); 76 } 77 78 /* 矩形拖拉 */ 79 public void drag(AnchorPane an) { 80 an.setOnMousePressed(new EventHandler<MouseEvent>() { 81 @Override 82 public void handle(MouseEvent arg0) { 83 84 an.getChildren().clear(); 85 86 hbox = new HBox(); 87 hbox.setBackground(null); 88 hbox.setBorder(new Border(new BorderStroke(Paint.valueOf("#CD3700"), BorderStrokeStyle.SOLID, null, 89 new BorderWidths(2)))); 90 /* 获取坐标 */ 91 sceneX_start = arg0.getSceneX(); 92 sceneY_start = arg0.getSceneX(); 93 94 an.getChildren().add(hbox); 95 96 AnchorPane.setLeftAnchor(hbox, sceneX_start); 97 AnchorPane.setTopAnchor(hbox, sceneY_start); 98 } 99 100 }); 101 /* 拖拽检测 */ 102 an.setOnDragDetected(new EventHandler<MouseEvent>() { 103 @Override 104 public void handle(MouseEvent event) { 105 // TODO 自动生成的方法存根 106 an.startFullDrag(); 107 } 108 109 }); 110 /* 拖拽获取坐标 */ 111 an.setOnMouseDragOver(new EventHandler<MouseEvent>() { 112 @Override 113 public void handle(MouseEvent event) { 114 115 Label label = new Label(); 116 label.setAlignment(Pos.CENTER); 117 label.setPrefWidth(170); 118 label.setPrefHeight(30); 119 120 an.getChildren().add(label); 121 122 AnchorPane.setLeftAnchor(label, sceneX_start); 123 AnchorPane.setTopAnchor(label, sceneY_start - label.getPrefHeight()); 124 125 label.setTextFill(Paint.valueOf("#ffffff")); 126 label.setStyle("-fx-background-color:#000000"); 127 128 double sceneX = event.getSceneX(); 129 double sceneY = event.getSceneY(); 130 131 double width = sceneX - sceneX_start; 132 double height = sceneY - sceneY_start; 133 134 hbox.setPrefWidth(width); 135 hbox.setPrefHeight(height); 136 137 label.setText("宽度:" + width + "高度:" + height); 138 139 } 140 141 }); 142 /*当鼠标拖拽出矩形后,可以通过点击完成,得到截图*/ 143 an.setOnMouseDragExited(new EventHandler<MouseDragEvent>() { 144 @Override 145 public void handle(MouseDragEvent event) { 146 // TODO 自动生成的方法存根 147 sceneX_end = event.getSceneX(); 148 sceneY_end = event.getSceneY(); 149 150 Button btn_fin = new Button("完成"); 151 hbox.getChildren().add(btn_fin); 152 hbox.setAlignment(Pos.BOTTOM_RIGHT); 153 154 btn_fin.setOnAction(new EventHandler<ActionEvent>() { 155 public void handle(ActionEvent arg0) { 156 // TODO 自动生成的方法存根 157 try { 158 getScreenImg(); 159 } catch (Exception e) { 160 // TODO 自动生成的 catch 块 161 e.printStackTrace(); 162 } 163 } 164 }); 165 } 166 }); 167 168 } 169 170 public void getScreenImg() throws Exception { 171 stage.close();// 关闭当前窗口 172 double w = sceneX_end - sceneX_start; 173 double h = sceneY_end - sceneY_start; 174 175 /*截图*/ 176 Robot robot = new Robot(); 177 Rectangle rec = new Rectangle((int) sceneX_start, (int) sceneY_start, (int) w, (int) h); 178 BufferedImage buffimg = robot.createScreenCapture(rec); 179 180 /*将图片显示在面板上*/ 181 WritableImage wi = SwingFXUtils.toFXImage(buffimg, null); 182 iv.setImage(wi); 183 184 /* 获取系统剪切板 */ 185 Clipboard cb = Clipboard.getSystemClipboard(); 186 187 /* 将图片放在剪切板上 */ 188 ClipboardContent content = new ClipboardContent(); 189 content.putImage(wi); 190 cb.setContent(content); 191 /* 写入图片到D盘 */ 192 ImageIO.write(buffimg, "png", new File("D:/img.png")); 193 primary.setIconified(false); 194 195 } 196 }
实验效果: