【爲生活開發系列之四】圖片文字識別與標準文檔對比工具

前言

我:測試?測試?測試? 5s後 測試:剛剛在對比網頁上圖片上的文字和標準文檔裏面的文字是否是同樣的,看的老孃眼都廢了,沒空理你。 我:。。。。。。這麼low的嗎? 測試:莫非這位兄臺有高見? 我:稍等。。。好了,能夠了,來試試? 。。。 測試:666html

效果預覽

效果預覽

目標需求與實現需求的思路

因爲每次上線活動或者運營報告的時候,網頁上的不少內容直接就是UI弄好的圖片,UI將圖片給前端,前端直接顯示這些圖片,可是UI在製做這些圖片的時候可能複製錯內容,因此測試須要在每次上下前檢查這些內容是否正確,原始的作法是電腦左邊顯示網頁,右邊顯示標準文檔,一個字一個字的檢查,這種方式不只慢,效率低並且容易出錯,因此須要咱們的時候到了。前端

需求:

給定須要檢查的圖片,識別圖片上的內容,而後與標準文檔裏面的內容進行比較,找出錯別字,提交給前端和UI設計師修改。爲了交互友好,咱們須要作一個可視化界面進行操做。因爲圖片的識別可能會出錯,因此咱們須要在界面上實時的顯示出被檢測的圖片,而後在對比出錯的時候檢查圖片識別是否出問題了。java

就拿上面的例子來講明,咱們識別的標準文檔在最上面,目標標準內容是上面輸入內容去掉全部的標點符號和空格後的內容,識別圖片內容是識別的圖片上的內容,在咱們第一次點擊開始比較的時候,顯示的是匹配不成功,咱們拖動進度條以後發現,標準內容比咱們識別出來的內容多一個「平」字,咱們檢查下面的圖片後發現,這個「平」字是存在的,只是識別的時候出現了問題,那麼咱們就認爲這個不算錯誤,咱們刪掉目標內容中的「平」字,而後再一次進行比較,此時顯示對比成功,那麼咱們認爲這個圖片中的內容與標準文檔中的內容是一致的。雖然也仍是存在一些偏差,可是這中方式的效率的正確率已是以前那種方式的好幾倍了。^_^git

實現需求的思路

核心功能是圖片的識別,以前瞭解到百度雲下有一個技術是圖片文字識別的技術,正好能夠派上用場了。 百度雲文字識別快速入門,連接是 https://cloud.baidu.com/doc/OCR/OCR-Java-SDK.html#.E5.BF.AB.E9.80.9F.E5.85.A5.E9.97.A8,用法很簡單,首先註冊帳號,獲取對應的key,secret和id啥的,而後免費版的一天能夠最多識別圖片500次,對於咱們測試來講,足矣。github

其次,識別出圖片上的文字以後,咱們須要將識別出的文字去掉全部空格和標點符號備用A1,獲取標準內容後去掉全部空格和標點符號備用A2,而後比較A1和A2,若是是同樣的就表示匹配成功,若是不同,咱們監聽識別圖片內容的文本框的滑動條B2,在咱們滑動這個滑動條的時候,動態的去滑動目標標準內容的滑動條B1,這樣的目的是爲了方便的找出不一致的文字所在的地方,找到地方以後,判斷是識別問題仍是真的有問題,再作相應的處理便可。json

代碼實現

因爲時間比較緊,因此有些處理不是很好,之後有時間了再優化,好比去除空格和標符號的處理,就至關low逼,你們忍忍吧。安全

package com.cretin;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import org.json.JSONArray;
import org.json.JSONObject;

import com.baidu.aip.ocr.AipOcr;

/** * <p> * Title: TupianShibie * </p> * <p> * Description: * </p> * <p> * Company: www.cretin.com * </p> * * @author cretin * @date 2018年2月2日 */
public class TupianShibie extends JFrame {
	private static final long serialVersionUID = 1L;
	// 設置APPID/AK/SK
	public static final String APP_ID = "YOUR APP_ID";
	public static final String API_KEY = "YOUR API_KEY";
	public static final String SECRET_KEY = "YOUR SECRET_KEY";

	// 設置寬高
	private static int mWidth = 1000;
	private static int mHeight = 800;

	// 當前選擇的文件
	private String currFilePath = "";

	// 控件
	private JPanel mainPanel;

	public TupianShibie() {
		setTitle("圖片識別與文字對比助手");

		// 獲取屏幕寬度
		Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
		mWidth = (int) ((int) screensize.getWidth() * 0.9);
		mHeight = (int) ((int) screensize.getHeight() * 0.9);
		setSize(mWidth, mHeight);
		setResizable(false);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		mainPanel = new JPanel();
		mainPanel.setLayout(null);

		// 標準內容區域
		JLabel label1 = new JLabel("請輸入標準內容");
		label1.setBounds(10, 20, 100, 20);
		mainPanel.add(label1);
		JTextArea textArea = new JTextArea();
		textArea.setLineWrap(true);// 設置文本區的換行策略
// 測試時使用 省得每次都輸入內容
// textArea.setText(
// "新春佳節事後,萬象更新,人們飽含着新的但願朝着新的目標,整裝待發、再啓征程。狗年伊始,網貸行業的發展示狀是怎麼樣的?房融界又有哪些規劃呢?2018網貸備案年正式開啓,隨着監管政策一步一步的落實,各網貸平臺加速合規,全力迎接4月份的終極「大考」。同時,在備案關鍵期,平臺對資產資質審覈也將愈來愈嚴格,投資人將面臨繼年關事後的又一段「投標荒」時期。\n"
// + " 順利完成備案登記將是房融界接下來工做的重中之重。2018年1月份,房融界已經向前海管理局提交了所有自查資料,並遵循政策的指引,根據律所和會計所出具的建議書加速合規整改,力爭今年備案成功。同時,爲解決當前投資人搶標困難的狀況,房融界已經對接了車貸、消費分期等符合監管規定的優質的資產,並計劃於近期上線。進行合規建設的同時,房融界也一直不敢放鬆對風控體系和用戶體驗的打造,今年房融界會繼續借助科技的力量完善風控、打磨產品,提高平臺服務品質。厚積「搏8」,「犬力」以赴。2018,房融界將在合規的路上繼續砥礪前行,努力爲投資人構建更安全、更可靠的投資環境。");
		JScrollPane jsp0 = new JScrollPane(textArea);
		jsp0.setBounds(116, 10, mWidth - 10 - 120 - 100, 100);
		jsp0.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		mainPanel.add(jsp0);

		// 兩個按鈕
		JButton jButton1 = new JButton("打開圖片");
		JButton jButton2 = new JButton("開始比較");
		JButton jButton3 = new JButton("清空數據");
		jButton1.setBounds(mWidth - 100, 15, 90, 30);
		jButton2.setBounds(mWidth - 100, 45, 90, 30);
		jButton3.setBounds(mWidth - 100, 75, 90, 30);
		mainPanel.add(jButton1);
		mainPanel.add(jButton2);
		mainPanel.add(jButton3);
		add(mainPanel);

		// 目標標準內容
		JLabel label2 = new JLabel("目標標準內容");
		label2.setBounds(10, 130, 100, 20);
		JTextField jTextField = new JTextField();
		JScrollPane jsp = new JScrollPane(jTextField);
		jsp.setBounds(116, 120, mWidth - 10 - 120, 60);
		jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		jsp.getHorizontalScrollBar().setEnabled(false);
		mainPanel.add(label2);
		mainPanel.add(jsp);

		// 識別圖片內容
		JLabel label3 = new JLabel("識別圖片內容");
		label3.setBounds(10, 200, 100, 20);
		JTextField jTextField1 = new JTextField();
		jTextField1.setEditable(false);
		JScrollPane jsp1 = new JScrollPane(jTextField1);
		jsp1.setBounds(116, 190, mWidth - 10 - 120, 60);
		jsp1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		mainPanel.add(label3);
		mainPanel.add(jsp1);

		// 所選圖片預覽
		JLabel label4 = new JLabel("所選圖片預覽");
		label4.setBounds(10, 270, 100, 20);
		mainPanel.add(label4);
		JLabel label = new JLabel();
		JScrollPane jsp2 = new JScrollPane(label);
		int picHeight = mHeight - 260;
		jsp2.setBounds(116, 260, mWidth - 20 - 110, picHeight - 130);
		mainPanel.add(jsp2);

		// 對比結果預覽
		JLabel label5 = new JLabel("操做控制檯");
		label5.setBounds(10, 270 + picHeight - 130 + 10, 100, 20);
		mainPanel.add(label5);
		JTextArea textArea1 = new JTextArea();
		JScrollPane jsp3 = new JScrollPane(textArea1);
		jsp3.setBounds(116, 260 + picHeight - 130 + 10, mWidth - 20 - 110, mHeight - (260 + picHeight - 130 + 10 + 30));
		jsp3.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		mainPanel.add(jsp3);

		add(mainPanel);

		// 添加事件
		// 選擇文件夾
		jButton1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// 檢查內容
				String tag = textArea.getText();
				if (tag == null || tag.equals("")) {
					JOptionPane.showMessageDialog(getContentPane(), "請先輸入標準內容再操做", "系統信息", JOptionPane.WARNING_MESSAGE);
					return;
				}
				JFileChooser jfc = new JFileChooser();
				jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
				jfc.showDialog(new JLabel(), "選擇文件夾");
				File file = jfc.getSelectedFile();
				if (file != null) {
					textArea1.append("已選擇文件:" + file.getAbsolutePath() + "\n");
					ImageIcon img = new ImageIcon(file.getAbsolutePath());// 建立圖片對象
					label.setIcon(img);
					currFilePath = file.getAbsolutePath();
				} else {
					textArea1.append("取消選擇文件......\n");
				}
			}
		});

		// 開始對比
		jButton2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (currFilePath != "" && !currFilePath.equals("")) {
					String tag = textArea.getText();
					doInt(tag, currFilePath, textArea1, jTextField, jTextField1,jButton2);
				} else {
					JOptionPane.showMessageDialog(getContentPane(), "請先選擇圖片再操做", "系統信息", JOptionPane.WARNING_MESSAGE);
				}
			}
		});
        //清空數據
		jButton3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// 清空全部數據
				textArea1.append("清空全部數據,準備進行下一次操做!!!\n");
				jTextField.setText("");
				jTextField1.setText("");
				textArea.setText("");
				//清空圖片
				label.setIcon(null);
				currFilePath = "";
				jButton2.setEnabled(true);
			}
		});
		// 對滑動條進行監聽
		JScrollBar bar = jsp1.getHorizontalScrollBar();
		bar.addAdjustmentListener(new AdjustmentListener() {

			@Override
			public void adjustmentValueChanged(AdjustmentEvent e) {
                //獲取到標準內容的滑動條 並將目前滑動的進度傳給他
				jsp.getHorizontalScrollBar().setValue(e.getValue());
			}
		});
		// 顯示窗體
		setVisible(true);
	}

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

	private void doInt(String aimStr, String path, JTextArea textArea1, JTextField jTextField, JTextField jTextField1, JButton jButton2) {
		String aimStr1 = "";
		String content = jTextField.getText();
		if (content == "" || content.equals("")) {
			aimStr1 = formatStr(aimStr);
			jTextField.setText(aimStr1);
		}else {
			aimStr1 = content;
		}
		final String aimStr2 = aimStr1;
		jButton2.setEnabled(false);
		textArea1.append("正在對比,請等待...\n");
		// 初始化一個AipOcr
		AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
		// 可選:設置網絡鏈接參數
		client.setConnectionTimeoutInMillis(2000);
		client.setSocketTimeoutInMillis(60000);
		new Thread() {
			public void run() {
				// 調用接口
				JSONObject res = client.basicGeneral(path, new HashMap<String, String>());
				JSONArray array = res.getJSONArray("words_result");
				Iterator<Object> it = array.iterator();
				StringBuffer stringBuffer = new StringBuffer();
				while (it.hasNext()) {
					JSONObject ob = (JSONObject) it.next();
					String ss = ob.getString("words");
					stringBuffer.append(ss);
				}
				String endStr = formatStr(stringBuffer.toString());
				jTextField1.setText(endStr);
				textArea1.append("對比完成!!!\n");
				if (endStr.equals(aimStr2)) {
					textArea1.append("對比結果:匹配成功\n");
					JOptionPane.showMessageDialog(getContentPane(), "恭喜,匹配成功", "系統信息", JOptionPane.INFORMATION_MESSAGE);
				} else {
					textArea1.append("對比結果:匹配不成功,請檢查\n");
					JOptionPane.showMessageDialog(getContentPane(), "匹配不成功,請注意", "系統信息", JOptionPane.WARNING_MESSAGE);
				}
				jButton2.setEnabled(true);
			};
		}.start();

	}

	// 去除標點符號 去除換行和空格
	private static String formatStr(String aimStr) {
		aimStr = aimStr.trim();
		// 對aimStr 去除標點符號 去除換行和空格
		aimStr = aimStr.replaceAll("\\n", "");
		aimStr = aimStr.replaceAll("\\r", "");
		aimStr = aimStr.replaceAll("\\t", "");
		aimStr = aimStr.replaceAll(",", "");
		aimStr = aimStr.replaceAll("。", "");
		aimStr = aimStr.replaceAll(",", "");
		aimStr = aimStr.replaceAll("、", "");
		aimStr = aimStr.replaceAll("\\.", "");
		aimStr = aimStr.replaceAll("(", "");
		aimStr = aimStr.replaceAll(")", "");
		aimStr = aimStr.replaceAll("\\)", "");
		aimStr = aimStr.replaceAll("\\(", "");
		aimStr = aimStr.replaceAll("!", "");
		aimStr = aimStr.replaceAll("!", "");
		aimStr = aimStr.replaceAll("\\?", "");
		aimStr = aimStr.replaceAll("?", "");
		aimStr = aimStr.replaceAll("「", "");
		aimStr = aimStr.replaceAll("\\:", "");
		aimStr = aimStr.replaceAll(":", "");
		aimStr = aimStr.replaceAll(";", "");
		aimStr = aimStr.replaceAll("\\;", "");
		aimStr = aimStr.replaceAll("」", "");
		aimStr = aimStr.replaceAll("\"", "");
		aimStr = aimStr.replaceAll(" ", "");
		return aimStr;
	}
}
複製代碼

相關鏈接

百度雲文字識別快速入門,連接是 https://cloud.baidu.com/doc/OCR/OCR-Java-SDK.html#.E5.BF.AB.E9.80.9F.E5.85.A5.E9.97.A8網絡

百度雲文字識別sdk下載,連接是 http://ai.baidu.com/sdkapp

GIthub項目QuickMapping,連接是 https://github.com/MZCretin/QuickMappingjsp

本項目代碼也已經上傳github了,能夠直接使用項目中的jar文件,另外你們須要本身去申請帳號哦,爲了測試能正常使用,個人帳號就不暴露了,謝謝理解。

我就是比較喜歡用代碼解決生活中的問題,感受很開心,哈哈哈。也喜歡你們關注個人簡書,掘金,Github和CSDN。

簡書首頁,連接是 https://www.jianshu.com/u/123f97613b86

掘金首頁,連接是 https://juejin.im/user/5838d57fac502e006c1708bc

Github首頁,連接是 https://github.com/MZCretin

CSDN首頁,連接是 http://blog.csdn.net/u010998327

我是Cretin,一個可愛的小男孩。

相關文章
相關標籤/搜索