快捷搜索:  汽车  科技

java快照分析(OCR识别护照一)

java快照分析(OCR识别护照一)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(); //姓名 privat

本系列文章将介绍一个使用OCR技术批量识别护照的桌面小工具的编写过程。使用到的主要技术为java、JavaFx、pdfbox等。最终代码将上传Github和Gitee。

OCR识别护照(二):护照识别及数据导出

需求描述

一个在国际学校做HR的朋友跟我说总是需要在OA系统或excel中录入外籍人员的护照信息,每次都需要打开pdf文件或图片对照填写,一旦遇到大批外籍员工入职或更换护照、签证信息时,工作量较大且容易出错。于是我利用业余时间给她写了一个小工具,可以批量识别护照。

新建javafx项目

在Idea中新建JavaFxApplication,取名passportScanner。

java快照分析(OCR识别护照一)(1)

界面布局

使用Idea自带的javafx编辑工具,简单地实现程序的界面布局。

java快照分析(OCR识别护照一)(2)

<?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="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" 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。

java快照分析(OCR识别护照一)(3)

在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后,界面如下图。

java快照分析(OCR识别护照一)(4)

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运行环境一起打包。

java快照分析(OCR识别护照一)(5)

java快照分析(OCR识别护照一)(6)

猜您喜欢: