LINEトークでOCRができるプログラムを3時間程度で開発したという記事を見て、JavaでOCRを試してみました。JavaでOCRを実現するのに、無料APIがありましたので早速使ってみます。
開発環境
IDE:Eclipse
Java8
FW:なし。ネイティブで作成
API:tess4j
<tess4jセットアップ>
Maven: https://mvnrepository.com/artifact/net.sourceforge.tess4j/tess4j
言語認識ファイル: https://github.com/tesseract-ocr/tessdata
uploadフォルダを作成
Viewから受け取ったファイルを置く場所を作成します。
ファイルの作成場所は、
WebContent/WEB-INF/upload
としてください。
Filter Classでutf-8を設定
まずは、文字化け防止のためFilterクラスを作成し、utf-8を設定します。
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* Servlet Filter implementation class filter
*/
@WebFilter("/filter")
public class filter implements Filter {
/**
* Default constructor.
*/
public filter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
request.setCharacterEncoding("utf-8");
response.setContentType("text/html:charset=utf8");
// pass the request along the filter chain
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
Servlet作成
Servletを作成する前に、こちらから実装したい言語ファイルをダウンロードし、ローカルに作業フォルダを作成して、言語ファイルを格納します。
今回、作業フォルダは C:\\Users\\workとしました。
言語ファイルは、この作業フォルダ直下にtessdataフォルダを作成し、セットしました。 C:\\Users\\work\\tessdata
package Controller;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import net.sourceforge.tess4j.ITessAPI.TessPageIteratorLevel;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import net.sourceforge.tess4j.Word;
/**
* Servlet implementation class TextChangeServlet
*/
@WebServlet("/TextChange")
@MultipartConfig(location = "C:\\Users\\work", maxFileSize = 500*500)
public class TextChangeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public TextChangeServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/views/textChange.jsp").forward(request,
response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
File uploadDirectory = new File(request.getServletContext().getRealPath("/WEB-INF/upload"));
Part part = request.getPart("file");
String filename = part.getSubmittedFileName();
part.write(getServletContext().getRealPath("/WEB-INF/upload" + "/" + filename));
// 検証用
System.out.println(uploadDirectory);
ITesseract tesseract = new Tesseract();
tesseract.setDatapath("C:\\Users\\work\\tessdata"); //言語ファイル格納先
// 日本語と英語で言語を変更
String lang = request.getParameter("lang");
switch(lang) {
case "jpn":
tesseract.setLanguage("jpn"); //言語を選択
break;
case "eng":
tesseract.setLanguage("eng"); //言語を選択
break;
default:
System.out.println("error");
}
File file = new File(uploadDirectory + "/" + filename);
BufferedImage img = ImageIO.read(file);
try {
List&lt;Word&gt; wordList = tesseract.getWords(img, TessPageIteratorLevel.RIL_BLOCK);
String str = tesseract.doOCR(img);
System.out.println(wordList);
System.out.println(str);
request.setAttribute("str", str);
request.getRequestDispatcher("/WEB-INF/views/textChange.jsp").forward(request, response);
} catch (TesseractException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
img = null;
}
}
}
@MultipartConfig(location = “C:\\Users\\work”, maxFileSize = 500*500)
@MultipartConfigでは、”location”で作業ファイルへの絶対パスを設定します。”maxFileSize”で、アップロードファイルの許容サイズを設定します。アップロードサイズを超えた場合、Webコンテナが IllegalStateExceptionをスローします。
POST通信がされたら、画像をuploadフォルダに入れる→変換言語の認識→tess4jで画像からテキストを判断→JSPに変換内容をはきだす流れになります。
JSP作成
WEB-INF直下にlibフォルダを作成し、JSTLを格納する。JSP上部でtaglib呼び出し。
<%@ page pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>画像から文字を起こすよ</title>
</head>
<body>
<h1>画像から文字をおこします</h1>
<p>文字を起こしたい画像をアップロードしてください。</p>
<ul>
<li><strong>注意事項</strong></li>
<li>画像は1枚のみアップロードしてください。PDFも1枚のみ</li>
<li>アップロード画像の容量は500MBまでです。</li>
</ul>
<form action="" method="post" enctype="multipart/form-data">
<p>
文字起こしをしたい言語を選択してください:<select name="lang">
<option value="jpn" selected>日本語</option>
<option value="eng">英語</option>
</select>
</p>
<input type="file" name="file" /><br /> <input type="submit"
value="アップロード" />
</form>
<section>
<pre style="font-size:16px; color:red;"><c:out value="${str}" /></pre>
</section>
</body>
</html>
以上!!

