assetのzipファイルを展開する
起動時に assets の tessdata.zip を展開する。
■展開元
tessdata.zip
■展開先
/data/data/com.example.android.tesseract/files
zipファイルをそのまま展開するので、
- tessdata.zip
- tessdata
- eng.traineddata
- tessdata
という構成になっていること。
MainActivity.java
package com.example.android.tesseract; import com.googlecode.tesseract.android.TessBaseAPI; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); new AssetInstaller2(this, mHandler).execute(); } private static MainHandler extends Handler { private final WeakReference<MainActivity> mActivity; MainHandler(MainActivity activity) { mActivity = new WeakReference<MainActivity>(activity); } @Override public void handleMessage(Message msg) { switch (msg.what) { case AssetInstaller.SHOW_TEXT: MainActivity activity = mActivity.get(); if (activity != null) { showTextView(); } } } }); private MainHandler mHandler = new MainHandler(this); private void showTextView() { String text = getText(); TextView textView = new TextView(MainActivity.this); textView.setText(text); setContentView(textView); } private String getText() { final Bitmap bitmap = BitmapFactory.decodeResource( getResources(), R.drawable.sample); final Bitmap copy = bitmap.copy(Config.ARGB_8888, true); final String path = getFilesDir().getPath(); TessBaseAPI baseApi; baseApi = new TessBaseAPI(); baseApi.init(path, "eng"); baseApi.setImage(copy); String text = baseApi.getUTF8Text(); baseApi.end(); return text; } }
AssetInstaller.java
package com.example.android.tesseract; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import android.app.ProgressDialog; import android.content.Context; import android.content.res.AssetFileDescriptor; import android.os.AsyncTask; import android.os.Handler; public class AssetInstaller2 extends AsyncTask<Void, Integer, Void> { public static final int SHOW_TEXT = 0; private static String ASSET_TESSDATA = "tessdata.zip"; private Context mContext; private Handler mHandler; private ArrayList<String> mZippedFiles; private long mTotalSize; private ProgressDialog mProgressDialog; public AssetInstaller2(Context context, Handler handler) { mContext = context; mHandler = handler; } @Override protected Void doInBackground(Void... params) { try { File filesDir = mContext.getFilesDir(); if (!checkToCopyFile(filesDir)) { return null; } startToCopyFile(filesDir); } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onProgressUpdate(Integer... values) { if (mProgressDialog == null) { showProgress((int)mTotalSize); } else { updateProgress(values[0]); } } @Override protected void onPostExecute(Void result) { dismissProgress(); mHandler.sendEmptyMessage(SHOW_TEXT); } private ZipInputStream getAssetZipInputStream() throws IOException { AssetFileDescriptor fd = mContext.getResources().getAssets().openFd( ASSET_TESSDATA); assert(fd != null); return new ZipInputStream(new BufferedInputStream( fd.createInputStream())); } private boolean checkToCopyFile(final File filesDir) throws IOException { assert(filesDir != null); mZippedFiles = new ArrayList<String>(); mTotalSize = 0; ZipInputStream zis = null; try { zis = getAssetZipInputStream(); ZipEntry zipEntry; while ((zipEntry = zis.getNextEntry()) != null) { if (zipEntry.isDirectory()) { zis.closeEntry(); continue; } long zipEntrySize = zipEntry.getSize(); String zipEntryName = zipEntry.getName(); File unzippedFile = new File(filesDir, zipEntryName); long unzippedFileSize = unzippedFile.length(); if (zipEntrySize != unzippedFileSize) { mZippedFiles.add(zipEntryName); mTotalSize += zipEntrySize; } zis.closeEntry(); } } finally { if (zis != null) zis.close(); } return !mZippedFiles.isEmpty(); } private void startToCopyFile(final File filesDir) throws IOException { assert(filesDir != null); assert(mZippedFiles != null); assert(!mZippedFiles.isEmpty()); copyFiles(filesDir); } private void copyFiles(final File filesDir) throws IOException { assert(filesDir != null); assert(mZippedFiles != null); assert(!mZippedFiles.isEmpty()); publishProgress(); ZipInputStream zis = null; try { zis = getAssetZipInputStream(); ZipEntry zipEntry; while ((zipEntry = zis.getNextEntry()) != null) { if (zipEntry.isDirectory()) { zis.closeEntry(); continue; } String zipEntryName = zipEntry.getName(); if (!mZippedFiles.contains(zipEntryName)) { zis.closeEntry(); continue; } File unzippedFile = new File(filesDir, zipEntryName); if (!unzippedFile.getParentFile().exists()) unzippedFile.getParentFile().mkdirs(); if (unzippedFile.exists()) unzippedFile.delete(); OutputStream os = null; try { os = new BufferedOutputStream( new FileOutputStream(unzippedFile)); byte[] buf = new byte[256]; int len; while ((len = zis.read(buf, 0, buf.length)) != -1) { os.write(buf, 0, len); publishProgress(buf.length); } os.flush(); } finally { if (os != null) os.close(); } unzippedFile.setReadable(true, false); unzippedFile.setWritable(true, false); zis.closeEntry(); } } finally { if (zis != null) zis.close(); } } private void showProgress(final int max) { mProgressDialog = new ProgressDialog(mContext); mProgressDialog.setIndeterminate(false); mProgressDialog.setProgressStyle( ProgressDialog.STYLE_HORIZONTAL); mProgressDialog.setCancelable(false); mProgressDialog.setMax(max); mProgressDialog.incrementProgressBy(0); mProgressDialog.show(); } private void updateProgress(final int diff) { assert(mProgressDialog != null); mProgressDialog.incrementProgressBy(diff); mProgressDialog.show(); } private void dismissProgress() { if (mProgressDialog != null) mProgressDialog.dismiss(); } }
ソースを書く前のメモ
- assetsにはzipファイルを配置する
- 非圧縮の場合、サイズ制限がある
- unzip前にファイルサイズのチェック
- unzipは別スレッド処理
- eng.traineddataは3MBくらいあるので、コピーに時間がかかる
- ProgressDialog表示
- unzipしたファイルにRW権限を付与
- 権限がないとtesseractが落ちる?