package com.lwy.ocrdemo; import android.annotation.SuppressLint; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.googlecode.tesseract.android.TessBaseAPI; import com.lwy.ocrdemo.utils.FileUtil; import com.lwy.ocrdemo.utils.PictureHandler; import com.lwy.ocrdemo.utils.ThreadManager; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by lwy on 2018/7/4. */ public class ResultActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "ResultActivity"; private Handler mHandler; private ProgressDialog mDialog; private TextView mTextView2; private TextView mTextView3; private TextView mTextView4; private TextView mTextView5; private TextView mTextView6; private TextView mTextView7; private static final String DATA_PATH = Environment.getExternalStorageDirectory().toString() + "/Tess"; /** * 在DATAPATH中新建这个目录,TessBaseAPI初始化要求必须有这个目录。 */ private static final String tessdata = DATA_PATH + File.separator + "tessdata"; public static String language = "chi_sim"; private ImageView mImageView1; private ImageView mImageView2; private ImageView mImageView3; private ImageView mImageView4; private ImageView mImageView5; private ImageView mImageView6; private ImageView mImageView7; private TextView mPicTimetv; private TextView mRecTimetv; private long mPicTimeStart; private long mPicTimeEnd; private long mRecTimeStart; private long mRecTimeEnd; private Bitmap[] mBitmaps; private int mRecogRunningCount; static class MyHandler extends Handler { private WeakReference<ResultActivity> wf; public MyHandler(ResultActivity activity) { wf = new WeakReference(activity); } @Override public void handleMessage(Message msg) { if (wf.get() != null) { ResultActivity activity = wf.get(); switch (msg.what) { case 1: activity.handleRecogResult(msg); if (--activity.mRecogRunningCount == 0) { activity.mRecTimeEnd = System.currentTimeMillis(); activity.mRecTimetv.setText("文字识别耗时:" + (activity.mRecTimeStart - activity.mRecTimeEnd)); if (activity.mDialog != null && activity.mDialog.isShowing()) { activity.mDialog.cancel(); } } break; case 2: if (activity.mDialog != null && activity.mDialog.isShowing()) { activity.mDialog.cancel(); } activity.handleBitmap(); break; case 0: Toast.makeText(activity, String.format("识别失败:%s", msg.obj), Toast.LENGTH_SHORT).show(); break; } } } } @SuppressLint("HandlerLeak") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_result); initView(); init(); } private void init() { File dataDir = new File(tessdata); if (!dataDir.exists()) { dataDir.mkdirs(); mDialog = new ProgressDialog(ResultActivity.this); mDialog.setMessage("拷贝训练数据中......"); mDialog.setCanceledOnTouchOutside(false); mDialog.show(); ThreadManager.getInstance().createLongPool().execute(new Runnable() { @Override public void run() { Message msg; try { FileUtil.assets2SDCard(ResultActivity.this, "chi_sim.traineddata", tessdata + File.separator + language + ".traineddata"); msg = Message.obtain(); msg.what = 2; } catch (IOException e) { msg = Message.obtain(); msg.what = 0; msg.obj = e.getMessage(); } mHandler.sendMessage(msg); } }); } else { handleBitmap(); } } private void initView() { mImageView1 = findViewById(R.id.image1); mImageView2 = findViewById(R.id.image2); mImageView3 = findViewById(R.id.image3); mImageView4 = findViewById(R.id.image4); mImageView5 = findViewById(R.id.image5); mImageView6 = findViewById(R.id.image6); mImageView7 = findViewById(R.id.image7); mTextView2 = findViewById(R.id.text2); mTextView3 = findViewById(R.id.text3); mTextView4 = findViewById(R.id.text4); mTextView5 = findViewById(R.id.text5); mTextView6 = findViewById(R.id.text6); mTextView7 = findViewById(R.id.text7); mPicTimetv = findViewById(R.id.pic_time_tv); mRecTimetv = findViewById(R.id.rec_time_tv); findViewById(R.id.button).setOnClickListener(this); mHandler = new MyHandler(this); } private void handleBitmap() { new AsyncTask<Void, Void, Bitmap[]>() { @Override protected void onPreExecute() { mDialog = new ProgressDialog(ResultActivity.this); mDialog.setMessage("图片处理中......"); mDialog.setCanceledOnTouchOutside(false); mDialog.show(); } @Override protected Bitmap[] doInBackground(Void... voids) { Bitmap[] bitmaps = new Bitmap[7]; mPicTimeStart = System.currentTimeMillis(); Bitmap bitmap; try { // 得到身份证 bitmap = Bytes2Bimap(StaticValue.sBitmaData); // FileInputStream bitmapInputStream = new FileInputStream(DATA_PATH + "/1.jpg"); //取本地图片做测试 // BitmapFactory.Options options = new BitmapFactory.Options(); // options.inPreferredConfig = Bitmap.Config.ARGB_8888; // bitmap = BitmapFactory.decodeStream(bitmapInputStream); bitmaps[0] = bitmap; // bitmap = PictureHandler.getBinaryImage(bitmap, PictureHandler.TYPE_MATRIX); int width = bitmap.getWidth(); int height = bitmap.getHeight(); // 得到姓名 bitmaps[1] = Bitmap.createBitmap(bitmap, width * 16 / 85, height * 2 / 55, width / 5, height * 11 / 55); bitmaps[1] = PictureHandler.getBinaryImage(bitmaps[1], PictureHandler.TYPE_MATRIX); // 得到性别 bitmaps[2] = Bitmap.createBitmap(bitmap, width * 16 / 85, height * 13 / 55, width / 10, height * 7 / 55); bitmaps[2] = PictureHandler.getBinaryImage(bitmaps[2], PictureHandler.TYPE_MATRIX); // 得到民族 bitmaps[3] = Bitmap.createBitmap(bitmap, width * 67 / 168, height * 13 / 55, width / 11, height * 7 / 55); bitmaps[3] = PictureHandler.getBinaryImage(bitmaps[3], PictureHandler.TYPE_MATRIX); // 得到出生年月 bitmaps[4] = Bitmap.createBitmap(bitmap, width * 16 / 85, height * 20 / 55, width * 30 / 85, height * 8 / 56); bitmaps[4] = PictureHandler.getBinaryImage(bitmaps[4], PictureHandler.TYPE_MATRIX); // 得到住址 bitmaps[5] = Bitmap.createBitmap(bitmap, width * 15 / 85, height * 27 / 55, width * 38 / 85, height * 15 / 55); bitmaps[5] = PictureHandler.getBinaryImage(bitmaps[5], PictureHandler.TYPE_MATRIX); // 得到身份证号码 bitmaps[6] = Bitmap.createBitmap(bitmap, width * 27 / 85, height * 44 / 55, width * 50 / 85, height * 7 / 55); bitmaps[6] = PictureHandler.getBinaryImage(bitmaps[6], PictureHandler.TYPE_MATRIX); } catch (final Exception e) { Log.d(this.getClass().getSimpleName(), e.toString()); Message msg = Message.obtain(); msg.what = 0; msg.obj = e.getMessage(); mHandler.sendMessage(msg); } return bitmaps; } @Override protected void onPostExecute(Bitmap[] bitmaps) { mBitmaps = bitmaps; mPicTimeEnd = System.currentTimeMillis(); mPicTimetv.setText("图像处理时间:" + (mPicTimeEnd - mPicTimeStart)); if (mBitmaps != null && mBitmaps.length > 00) { mImageView1.setImageBitmap(bitmaps[0]); mImageView2.setImageBitmap(bitmaps[1]); mImageView3.setImageBitmap(bitmaps[2]); mImageView4.setImageBitmap(bitmaps[3]); mImageView5.setImageBitmap(bitmaps[4]); mImageView6.setImageBitmap(bitmaps[5]); mImageView7.setImageBitmap(bitmaps[6]); mDialog.cancel(); } super.onPostExecute(bitmaps); } }.execute(); } private void handleRecogResult(Message msg) { int type = msg.arg1; switch (type) { case 1: mTextView2.setText((CharSequence) msg.obj); break; case 2: mTextView3.setText((CharSequence) msg.obj); break; case 3: mTextView4.setText((CharSequence) msg.obj); break; case 4: String time = (String) msg.obj; if (!TextUtils.isEmpty(time)) { Pattern pattern = Pattern.compile("^(\\d{4}).+(\\d{1,2}).+(\\d{1,2}).+$"); Matcher matcher = pattern.matcher(time); if (matcher.find()) { time = String.format("%s年%s月%s日", matcher.group(1), matcher.group(2), matcher.group(3)); } } mTextView5.setText(time); break; case 5: mTextView6.setText((CharSequence) msg.obj); break; case 6: mTextView7.setText((CharSequence) msg.obj); break; } } /** * 改变亮度 */ public Bitmap changeLight(Bitmap bitmap, int brightness) { ColorMatrix cMatrix = new ColorMatrix(); cMatrix.set(new float[]{1, 0, 0, 0, brightness, 0, 1, 0, 0, brightness,// 改变亮度 0, 0, 1, 0, brightness, 0, 0, 0, 1, 0}); Paint paint = new Paint(); paint.setColorFilter(new ColorMatrixColorFilter(cMatrix)); Canvas canvas = new Canvas(bitmap); // 在Canvas上绘制一个已经存在的Bitmap。这样,dstBitmap就和srcBitmap一摸一样了 canvas.drawBitmap(bitmap, 0, 0, paint); return bitmap; } /** * 放大图片 * * @param bitmap * @return */ private static Bitmap big(Bitmap bitmap, float num) { Matrix matrix = new Matrix(); matrix.postScale(num, num); //长和宽放大缩小的比例 Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight (), matrix, true); return resizeBmp; } /** * byte转Bitmap * * @param b * @return */ public Bitmap Bytes2Bimap(byte[] b) { if (b.length != 0) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; // options.inMutable = true; Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length, options); return bitmap; } else { return null; } } @Override public void onClick(final View view) { mDialog = new ProgressDialog(view.getContext()); mDialog.setMessage("识别中......"); mDialog.setCanceledOnTouchOutside(false); mDialog.show(); mRecTimeStart = System.currentTimeMillis(); ThreadManager.getInstance().createLongPool().execute(new RecRunnable(mBitmaps[1], 1, mHandler)); mRecogRunningCount++; ThreadManager.getInstance().createLongPool().execute(new RecRunnable(mBitmaps[2], 2, mHandler)); mRecogRunningCount++; ThreadManager.getInstance().createLongPool().execute(new RecRunnable(mBitmaps[3], 3, mHandler)); mRecogRunningCount++; ThreadManager.getInstance().createLongPool().execute(new RecRunnable(mBitmaps[4], 4, mHandler)); mRecogRunningCount++; ThreadManager.getInstance().createLongPool().execute(new RecRunnable(mBitmaps[5], 5, mHandler)); mRecogRunningCount++; ThreadManager.getInstance().createLongPool().execute(new RecRunnable(mBitmaps[6], 6, mHandler)); mRecogRunningCount++; } public static class RecRunnable implements Runnable { private int mType; private Handler mHandler; private Bitmap mBitmap; public RecRunnable(Bitmap bitmap, int type, Handler handler) { mBitmap = bitmap; mHandler = handler; mType = type; } @Override public void run() { String text = getText(mBitmap); Message msg = Message.obtain(); msg.what = 1; msg.obj = text; msg.arg1 = mType; mHandler.sendMessage(msg); } /** * 获取图片上的文字 * * @param bitmap * @return */ private String getText(Bitmap bitmap) { String retStr = "No result"; try { TessBaseAPI tessBaseAPI = new TessBaseAPI(); tessBaseAPI.init(DATA_PATH, language); // 识别黑名单 // tessBaseAPI.setVariable(TessBaseAPI.VAR_CHAR_BLACKLIST, "!@#$%^&*()_+=÷-[]}{;:'\"\\|~`," + // "./<>?" + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); tessBaseAPI.setImage(bitmap); retStr = tessBaseAPI.getUTF8Text(); tessBaseAPI.clear(); tessBaseAPI.end(); } catch (Exception e) { Message msg = Message.obtain(); msg.what = 0; msg.obj = e.getMessage(); mHandler.sendMessage(msg); } return retStr; } } }