實現小猿搜題、作業幫類似效果。
基於Google Tesseract-OCR實現,由於這是基於C++開發,Android中不能直接使用,所以本專案使用tess-two是對於Android的分支。
準備工作
1)Android Studio匯入gradle依賴(懶人做法)
//編譯好的SO庫 和 jar包
compile 'com.rmtheis:tess-two:6.1.1'
//影象裁剪
compile 'com.edmodo:cropper:1.0.1'複製程式碼
其實也可以自己下載github.com/rmtheis/tes…原始碼在Linux環境中進行編譯。
2)第二種方法 自己編譯原始碼(!!!)
- 安裝虛擬機器VMware
- 安裝linux系統Ubuntu
- 安裝必要工具
sudo apt-get update
sudo apt-get install git複製程式碼
- 配置JDK、NDK、SDK環境(踩了一萬個坑)
- 下載tess-two程式碼
git clone https://github.com/rmtheis/tess-two.git tess複製程式碼
- 開始編譯
cd /tess/tess-two/jni
ndk-build複製程式碼
- 使用
將編譯好的tess-two目錄複製到自己專案的libraries下,將專案下的app關聯 libraries。
tess-two使用
資料字典下載,在app/main目錄下新建assets目錄,從github.com/tesseract-o…下載對應語言的字典庫。
MainActivity.java
主要就是將assets中的字典檔案寫到手機檔案目錄
/**
* 將assets中的檔案複製出
*
* @param path
*/
public void deepFile(String path) {
String newPath = getExternalFilesDir(null) + "/";
try {
String str[] = getAssets().list(path);
if (str.length > 0) {//如果是目錄
File file = new File(newPath + path);
file.mkdirs();
for (String string : str) {
path = path + "/" + string;
deepFile(path);
path = path.substring(0, path.lastIndexOf('/'));//回到原來的path
}
} else {//如果是檔案
InputStream is = getAssets().open(path);
FileOutputStream fos = new FileOutputStream(new File(newPath + path));
byte[] buffer = new byte[1024];
int count = 0;
while (true) {
count++;
int len = is.read(buffer);
if (len == -1) {
break;
}
fos.write(buffer, 0, len);
}
is.close();
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}複製程式碼
點選跳轉到拍照介面
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_camera:
Intent intent = new Intent(this, TakePhoteActivity.class);
startActivity(intent);
break;
}
}複製程式碼
- TakePhoteActivity.java
主要執行拍照、裁剪操作。
以下是拍照成功後回掉介面,拍照成功後顯示剪裁介面
/**
* 拍照成功後回撥
* 儲存圖片並顯示截圖介面
*
* @param data
*/
@Override
public void onCameraStopped(byte[] data) {
Log.i("TAG", "==onCameraStopped==");
// 建立影象
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
// 系統時間
long dateTaken = System.currentTimeMillis();
// 影象名稱
String filename = DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString() + ".jpg";
// 儲存影象(PATH目錄)
Uri source = insertImage(getContentResolver(), filename, dateTaken, PATH, filename, bitmap, data);
//準備截圖
try {
mCropImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(this.getContentResolver(), source));
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
showCropperLayout();
}複製程式碼
剪裁操作,完成後跳轉到識別介面
private View.OnClickListener cropcper = new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_closecropper:
showTakePhotoLayout();
break;
case R.id.btn_startcropper:
//獲取截圖並旋轉90度
Bitmap cropperBitmap = mCropImageView.getCroppedImage();
Bitmap bitmap = Utils.rotate(cropperBitmap, -90);
// 系統時間
long dateTaken = System.currentTimeMillis();
// 影象名稱
String filename = DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString() + ".jpg";
Uri uri = insertImage(getContentResolver(), filename, dateTaken, PATH, filename, bitmap, null);
Intent intent = new Intent(TakePhoteActivity.this, ShowCropperedActivity.class);
intent.setData(uri);
intent.putExtra("path", PATH + filename);
intent.putExtra("width", bitmap.getWidth());
intent.putExtra("height", bitmap.getHeight());
// intent.putExtra("cropperImage", bitmap);
startActivity(intent);
bitmap.recycle();
finish();
break;
}
}
};複製程式碼
- ShowCropperedActivity.java
主要是識別操作
初始化識別器
//sd卡路徑
private static String LANGUAGE_PATH = "";
//識別語言
private static final String LANGUAGE = "chi_sim";//chi_sim | eng
private TessBaseAPI baseApi = new TessBaseAPI();
@Override
protected void onCreate(Bundle savedInstanceState) {
LANGUAGE_PATH = getExternalFilesDir("") + "/";
baseApi.init(LANGUAGE_PATH, LANGUAGE);
//設定設別模式
baseApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_AUTO);
}複製程式碼
將圖片灰度化處理,去除雜色可以提高準確度
/**
* 灰度化處理
*
* @param bitmap3
* @return
*/
public Bitmap convertGray(Bitmap bitmap3) {
colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
Paint paint = new Paint();
paint.setColorFilter(filter);
Bitmap result = Bitmap.createBitmap(bitmap3.getWidth(), bitmap3.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawBitmap(bitmap3, 0, 0, paint);
return result;
}複製程式碼
開始識別
//傳入圖片
baseApi.setImage(bitmap);
//獲取識別後的結果
String result = baseApi.getUTF8Text();
//結束識別
baseApi.end();複製程式碼
結果
Demo已上傳Github如需要可下載github.com/wangtaoT/An…