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>
以上!!