前言:
当前姐妹们对“javafx显示图片”大致比较珍视,我们都需要分析一些“javafx显示图片”的相关知识。那么小编在网摘上搜集了一些对于“javafx显示图片””的相关内容,希望兄弟们能喜欢,大家一起来学习一下吧!本系列文章将介绍一个使用OCR技术批量识别护照的桌面小工具的编写过程。使用到的主要技术为java、javafx、pdfbox等。最终代码将上传Github和Gitee。
OCR识别护照(二):护照识别及数据导出
需求描述
一个在国际学校做HR的朋友跟我说总是需要在OA系统或excel中录入外籍人员的护照信息,每次都需要打开pdf文件或图片对照填写,一旦遇到大批外籍员工入职或更换护照、签证信息时,工作量较大且容易出错。于是我利用业余时间给她写了一个小工具,可以批量识别护照。
新建javafx项目
在idea中新建JavaFxApplication,取名passportScanner。
界面布局
使用Idea自带的javafx编辑工具,简单地实现程序的界面布局。
<?xml version="1.0" encoding="UTF-8"?><?import javafx.geometry.*?><?import javafx.scene.control.*?><?import javafx.scene.layout.*?><?import javafx.scene.text.*?><AnchorPane prefHeight="500.0" prefWidth="1024.0" xmlns="; xmlns:fx="; fx:controller="org.xy.passportScanner.MainController"> <children> <VBox layoutX="14.0" layoutY="6.0" prefHeight="500.0" prefWidth="1024.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <children> <GridPane hgap="8.0" prefHeight="80.0" prefWidth="1024.0" vgap="12.0"> <columnConstraints> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="300.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="160.0" /> </columnConstraints> <rowConstraints> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="40.0" vgrow="SOMETIMES" /> </rowConstraints> <children> <Button fx:id="fileButton" mnemonicParsing="false" text="选择文件" GridPane.columnIndex="1"> <font> <Font size="14.0" /> </font></Button> <Label text="(png,jpg,bmp,pdf)" GridPane.columnIndex="1"> <GridPane.margin> <Insets left="90.0" /> </GridPane.margin> <font> <Font size="14.0" /> </font> </Label> <TextArea fx:id="filePath" editable="false" prefHeight="200.0" prefWidth="200.0" /> <HBox prefHeight="100.0" prefWidth="200.0" spacing="20.0" GridPane.columnSpan="2" GridPane.rowIndex="1"> <children> <Button fx:id="scanButton" graphicTextGap="8.0" layoutX="10.0" layoutY="10.0" minWidth="108.0" mnemonicParsing="false" text="开始识别"> <font> <Font size="20.0" /> </font> <opaqueInsets> <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> </opaqueInsets> </Button> <Label fx:id="tipLabel" prefHeight="40.0" wrapText="true"> <font> <Font size="18.0" /> </font> </Label> </children> </HBox> </children> <VBox.margin> <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" /> </VBox.margin> </GridPane> <AnchorPane prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS"> <children> <TableView fx:id="resultTable" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="420.0" prefWidth="1024.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> </children> </AnchorPane> </children> </VBox> </children></AnchorPane>设置界面大小、图标、标题
在resources/images文件夹中添加passport.png。
在Main.java的start方法中添加以下代码。
package org.xy.passportScanner;import javafx.scene.image.Image;import org.xy.passportScanner.config.GlobalData;import org.xy.passportScanner.config.Settings;import javafx.application.Application;import javafx.event.EventHandler;import javafx.fxml.FXMLLoader;import javafx.scene.Parent;import javafx.scene.Scene;import javafx.stage.Stage;import javafx.stage.WindowEvent;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.yaml.snakeyaml.Yaml;import org.yaml.snakeyaml.constructor.Constructor;import java.io.InputStream;public class Main extends Application { private static final Logger logger = LoggerFactory.getLogger(Main.class); @Override public void start(Stage primaryStage) throws Exception { //加载界面文件 Parent load = FXMLLoader.load(getClass().getClassLoader().getResource("main.fxml")); //设置窗口大小 Scene scene = new Scene(load, 1024, 500); primaryStage.setScene(scene); //设置标题和logo primaryStage.setTitle("PassportScanner"); primaryStage.getIcons().add(new Image("images/passport.png")); //显示页面 primaryStage.show(); //关闭事件处理 primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() { @Override public void handle(WindowEvent event) { System.exit(0); } }); } public static void main(String[] args) { launch(args); }}tableview绑定数据
新建PassportBean.java类,与不同javabean不同,所有属性均使用StringProperty,以便与javafx组件绑定数据。
package org.xy.passportScanner.data;import javafx.beans.property.SimpleStringProperty;import javafx.beans.property.StringProperty;public class PassportBean { //文件序号 private StringProperty id = new SimpleStringProperty(); //文件名 private StringProperty file = new SimpleStringProperty(); //护照号 private StringProperty number = new SimpleStringProperty(); //姓名 private StringProperty name = new SimpleStringProperty(); //性别 private StringProperty gender = new SimpleStringProperty(); //出生日期 private StringProperty birthday = new SimpleStringProperty(); //有效期 private StringProperty expireDate = new SimpleStringProperty(); //签发国 private StringProperty issuingCountry = new SimpleStringProperty(); //国籍 private StringProperty nationality = new SimpleStringProperty(); //备注 private StringProperty comments = new SimpleStringProperty(); public PassportBean(String id, String file, String number, String name, String gender, String birthday, String expireDate, String issuingCountry, String nationality, String comments){ this.id.set(id); this.file.set(file); this.number.set(number); this.name.set(name); this.gender.set(gender); this.birthday.set(birthday); this.expireDate.set(expireDate); this.issuingCountry.set(issuingCountry); this.nationality.set(nationality); this.comments.set(comments); } public PassportBean(){} public String getId() { return id.get(); } public StringProperty idProperty() { return id; } public void setId(String id) { this.id.set(id); } public String getFile() { return file.get(); } public StringProperty fileProperty() { return file; } public void setFile(String file) { this.file.set(file); } public String getNumber() { return number.get(); } public StringProperty numberProperty() { return number; } public void setNumber(String number) { this.number.set(number); } public String getName() { return name.get(); } public StringProperty nameProperty() { return name; } public void setName(String name) { this.name.set(name); } public String getGender() { return gender.get(); } public StringProperty genderProperty() { return gender; } public void setGender(String gender) { this.gender.set(gender); } public String getBirthday() { return birthday.get(); } public StringProperty birthdayProperty() { return birthday; } public void setBirthday(String birthday) { this.birthday.set(birthday); } public String getExpireDate() { return expireDate.get(); } public StringProperty expireDateProperty() { return expireDate; } public void setExpireDate(String expireDate) { this.expireDate.set(expireDate); } public String getIssuingCountry() { return issuingCountry.get(); } public StringProperty issuingCountryProperty() { return issuingCountry; } public void setIssuingCountry(String issuingCountry) { this.issuingCountry.set(issuingCountry); } public String getNationality() { return nationality.get(); } public StringProperty nationalityProperty() { return nationality; } public void setNationality(String nationality) { this.nationality.set(nationality); } public String getComments() { return comments.get(); } public StringProperty commentsProperty() { return comments; } public void setComments(String comments) { this.comments.set(comments); }}
在MainController的initialize方法中为tableview绑定数据
//初始化结果表resultTable.setItems(data);TableColumn<PassportBean,String> id = new TableColumn<PassportBean,String>("序号");id.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.05));id.setCellFactory(TextFieldTableCell.forTableColumn());id.setCellValueFactory(new PropertyValueFactory<PassportBean, String>("id"));id.getStyleClass().add("alarm-table");resultTable.getColumns().add(id);TableColumn<PassportBean,String> file = new TableColumn<PassportBean,String>("文件");file.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.15));file.setCellValueFactory(new PropertyValueFactory<PassportBean,String>("file"));file.getStyleClass().add("alarm-table");resultTable.getColumns().add(file);TableColumn<PassportBean,String> number = new TableColumn<PassportBean,String>("护照号");number.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.1));number.setCellValueFactory(new PropertyValueFactory<PassportBean,String>("number"));number.getStyleClass().add("alarm-table");resultTable.getColumns().add(number);TableColumn<PassportBean,String> name = new TableColumn<PassportBean,String>("姓名");name.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.25));name.setCellValueFactory(new PropertyValueFactory<PassportBean,String>("name"));name.getStyleClass().add("alarm-table");resultTable.getColumns().add(name);TableColumn<PassportBean,String> gender = new TableColumn<PassportBean,String>("性别");gender.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.05));gender.setCellValueFactory(new PropertyValueFactory<PassportBean,String>("gender"));gender.getStyleClass().add("alarm-table");resultTable.getColumns().add(gender);TableColumn<PassportBean,String> birthday = new TableColumn<PassportBean,String>("出生日期");birthday.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.1));birthday.setCellValueFactory(new PropertyValueFactory<PassportBean,String>("birthday"));birthday.getStyleClass().add("alarm-table");resultTable.getColumns().add(birthday);TableColumn<PassportBean,String> expireDate = new TableColumn<PassportBean,String>("有效期");expireDate.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.1));expireDate.setCellValueFactory(new PropertyValueFactory<PassportBean,String>("expireDate"));expireDate.getStyleClass().add("alarm-table");resultTable.getColumns().add(expireDate);TableColumn<PassportBean,String> issuingCountry = new TableColumn<PassportBean,String>("签发国");issuingCountry.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.05));issuingCountry.setCellValueFactory(new PropertyValueFactory<PassportBean,String>("issuingCountry"));issuingCountry.getStyleClass().add("alarm-table");resultTable.getColumns().add(issuingCountry);TableColumn<PassportBean,String> nationality = new TableColumn<PassportBean,String>("国籍");nationality.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.05));nationality.setCellValueFactory(new PropertyValueFactory<PassportBean,String>("nationality"));nationality.getStyleClass().add("alarm-table");resultTable.getColumns().add(nationality);TableColumn<PassportBean,String> comments = new TableColumn<PassportBean,String>("备注");comments.prefWidthProperty().bind(resultTable.widthProperty().multiply(0.1));comments.setCellValueFactory(new PropertyValueFactory<PassportBean,String>("comments"));comments.getStyleClass().add("alarm-table");resultTable.getColumns().add(comments);//模拟数据data.add(new PassportBean("1", "c:/123", "12345", "LI SI", "M", "20010302", "20250909", "CHN", "CHN", ""));data.add(new PassportBean("2", "c:/123", "12345", "LI SI", "M", "20010302", "20250909", "CHN", "CHN", ""));运行Main看看效果
至此,界面已经可以运行了。运行Main.main后,界面如下图。
javafx打包为exe程序
javafx打包使用的plugin为com.zenjava,详细配置如下:
如果需要修改默认的exe图标,则需要制作相应的ico图片,并放到指定目录下,如resources/images/passport.ico。
<plugin> <groupId>com.zenjava</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>8.8.3</version> <configuration> <!--运行类--> <mainClass>org.xy.passportScanner.Main</mainClass> <vendor>pegasus</vendor> <bundleArguments> <!-- 指示用户是否可以选择应用程序安装目录 --> <installdirChooser>true</installdirChooser> <!--exe图标--> <icon>${project.basedir}/src/main/resources/images/passport.ico</icon> </bundleArguments> <allPermissions>true</allPermissions> <!--添加到程序列表--> <needMenu>true</needMenu> <!--桌面快捷方式--> <needShortcut>true</needShortcut> </configuration></plugin>
配置好以后,执行maven clean package和jfx:build-native即可将javafx程序打包生成exe文件,同时将java运行环境一起打包。
标签: #javafx显示图片