はじめに
僕が通っている大学ではCMP実習という授業があり、そこでHTMLやCSS、JavaScriptを教えてもらいます。その課題で「JavaScriptのライブラリを使ったプログラムを作ってきてね」と言われたので僕はTESSERACT.jsという文字認識ライブラリを使いコード画像をテキストファイルに変えるWebサービス「ImageCode」を作りました。今回はそれを作った背景とコードについて解説していきたいと思います。
ImageCodeを作った理由
以前、プログラミングの記事を読んでいて「使いたい!」と思ったコードがありました。しかし、それをコピペすることができませんでした。なんとそのコード、画像ファイルだったんです。たぶんテキストエディタに書いたコードをスクショして貼り付けたのだと思います。仕方なく僕はそのコードを画像のまま写すことに……。
そうやって画像のコードを写すのは億劫でした。そこで僕は「コードの画像をそのままテキストファイルにすればいいのでは?」と考えてImageCodeを作りました。
環境設定
TESSERACT.js
画像に書いてある文章を文字認識してくれるライブラリです。現在、英語、中国語、ロシア語に対応しています。今回はプログラミングコードを文字認識するため、英語の文字認識を使います。ブラウザで使うときはHTMLに下記のURLをscriptタグに入れればOKです。
GitHubに上がっているサンプルは下記の通りです。
Tesseract.recognize(myImage)
.progress(function (p) { console.log('progress', p) })
.then(function (result) { console.log('result', result) })
このmyImageに画像URLを入力するとresultに文字を抽出した結果がJSON形式で返されます。progressは現在の進行状況を教えてくれます。今回は使わないので省きました。
画像ファイルを選択して表示させる
mementoo.info 上の記事を参考に自分のPCのフォルダーから画像を選択し、描画と画像情報の取得するコードを作りました。
HTML側
<img src="" id="original">
<input type="file" onchange="reader.readAsDataURL(this.files[0])">
var img = document.getElementById('original')
var reader = new FileReader()
reader.onload = function () {
//アップロードした画像データをimgタグに挿入
img.src = reader.result
}
original.onload = function () {
//画像をテキストデータに変える処理を書く
}
textareaの文字をテキストファイルとして保存
文字認識で取得したコードはtextareaに設定し、保存ボタンを押したらそれをテキストファイル化しダウンロードするようにします。
oshiete1.nifty.com textareaの文字列のテキストファイル化は上の記事を参考にしました。変更点は三つあります。まず今回は僕が親しんでいるpdeファイル(Processingのファイル)にしたいため「text/plain」を「application/processing」に、「.txt」を「.pde」に変えています。もう一つの変更点はデフォルトのファイル名を「myText」から「sketch」にしていますが、これは単純に好みです。
コードは以下の通りになります。
HTML側
<input id="name" placeholder="ファイル名">.pde<br>
<textarea id="text" rows="10" cols="50" value=""></textarea>
<button onclick="TextSave()">保存</button>
function TextSave() {
var text = document.getElementById('text').value
var name = document.getElementById('name').value || 'sketch'
var blob = new Blob([text], { type: 'application/processing' })
var link = document.getElementById('DL_link')
link.href = window.URL.createObjectURL(blob)
if ('download' in link) {
link.download = name + '.pde'
link.click()
} else {
link.textContent = '右クリックから名前を付けて保存してください'
}
}
最終コード
さてこれらのコードを組み合わせていきます! ついでにCSSも書きました。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ImageCode</title>
<link rel="stylesheet" href="./css/style.css">
<div id="inputer">
<input type="file" id="input" value=""
onchange="reader.readAsDataURL(this.files[0])">
<button onclick="TextSave()">保存</button>
<a id='DL_link'></a>
</div>
id="original">
tesseract.js/1.0.10/dist/tesseract.js'></script>
<script src="./js/main.js"></script>
</head>
<body>
<div id="code">
<h2>コード</h2>
<input id="name" placeholder="ファイル名">.pde<br>
<textarea id="text" rows="10" cols="50" value=""></textarea>
</div>
</body>
</html>
imgタグにはデフォルトで「画像をアップロード」と書かれた画像を挿入しています。
main.js
var img = document.getElementById('original')
var reader = new FileReader()
reader.onload = function () {
img.src = reader.result
}
//画像が変わったら実行
original.onload = function () {
//画像をテキストデータに変える
Tesseract.recognize(img)
.then(function (result) {
document.getElementById("text").value = result.blocks[0].text;
})
}
//テキストファイルを保存する関数
function TextSave() {
var text = document.getElementById('text').value
var name = document.getElementById('name').value || 'sketch'
var blob = new Blob([text], { type: 'application/processing' })
var link = document.getElementById('DL_link')
link.href = window.URL.createObjectURL(blob)
if ('download' in link) {
link.download = name + '.pde'
link.click()
} else {
link.textContent = '右クリックから名前を付けて保存してください'
}
}
img{
margin: 0px;
float : left;
width: 50%;
height: auto;
border: 5px solid #000;
}
#inputer{
float : right;
}
#code{
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 5%;
float : right;
}
@media screen and ( max-width:1000px ){
img{
width: 80%;
}
#inputer{
float : left;
}
#code{
float : left;
}
}
github.com
完成図
こちらのリンクからデモを体験できます。(ImageCode)僕は下の画像を使ってコード生成をしました。(ライブラリの性能的に誤字が発生するのでなるべく発生しないように工夫した画像ですので、)下の画像で試すのを推奨します。
推奨画像
最後に
生のJavaScriptに触れたことがあまりなく、授業で習ったばかりでHTMLやCSSの書き方もおぼつかないところがあると思いますが、なんとか完成させることができました。
今回はpdeファイル限定ですが、今後は他のファイルでも対応させたり、文字認識の性能を上げていきたいと思います。