1.SDK下载
去百度开放平台注册账号
选择文字识别
创建应用,包名应该与项目包名一致
创建完成后,就可以下载SDK
2.下载SDK解压到项目的lib目录
下载包libs目录中的ocr-sdk.jar、armeabi,arm64-v8a,armeabi-v7a,x86文件拷贝到工程libs目录中,并加入工程依赖。
在APP的build.gradle文件中添加代码
sourceSets{
main{
jniLibs.srcDirs 'libs'
}
}
在android模式下可以看到生成了jniLibs文件夹,脚本意思是会把libs文件夹当成jniLibs文件夹,可以直接用armeabi,arm64-v8a,armeabi-v7a,x86文件里的so库了
3.编写项目代码
activity_main.xml
<Button
android:onClick="click"
android:id="@+id/btn"
android:textSize="30sp"
android:text="@string/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:text="内容:"
android:id="@+id/txt"
android:gravity="left"/>
MainActivity包含了拍照回调并获取数据并设置数据
点击事件
public void click(View v) {
pohotouri = getphotoUri();
int hasCameraPermission = ContextCompat.checkSelfPermission(getApplication(),
Manifest.permission.CAMERA);
if (hasCameraPermission == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, pohotouri);
startActivityForResult(intent, TAKE_PHOTO);
//有调起相机拍照。
initAccessTokenWithAkSk();
//获取Token
} else {
//没有权限,申请权限。
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
PERMISSION_CAMERA_REQUEST_CODE);
}
}
initAccessTokenWithAkSk()的实现
rivate void initAccessTokenWithAkSk() {
OCR.getInstance(MainActivity.this).initAccessTokenWithAkSk(new OnResultListener<AccessToken>() {
public void onResult(AccessToken result) {
String token = result.getAccessToken();
Log.e("TGA", "token:" + token);
hasGotToken = true;
}
public void onError(OCRError error) {
Log.e("TGA", "AK,SK方式获取token失败");
error.printStackTrace();
Toast.makeText(MainActivity.this, "AK,SK方式获取token失败", Toast.LENGTH_LONG).show();
}
},getApplicationContext(), "填写AK", "SK");//用明文获取
}
把制作uri的路径文件设置为全局变量,以便调用百度服务时获取图片绝对路径,省去了uri转绝对路径的麻烦
private Uri getphotoUri() {
Uri photouri = null;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String sdDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "photo.jpg";
String path = sdDir + String.format("/%s/%s", "WUX", fileName);
file = new File(path);
if (file.exists()) {
file.delete();
}
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
photouri = FileProvider.getUriForFile(this, "com.wxstudy.ocr.FileProvider", file);
return photouri;
} else {
Toast.makeText(this, "请插入SD卡", Toast.LENGTH_LONG).show();
return photouri;
}
}
获取uri时还需在AndroidMainfest.xml文件中添加如下代码
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.wxstudy.ocr.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/images" />
</provider>
在res目录中创建xml文件夹,新建images.xml文件并加入代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
<external-path
name="external-path"
path="图片保存的路径"
>
</external-path>
</resources>
以上设置因为Android7.0以后,对于uri的获取做了限制
申请拍照权限的回调
/**
* 处理权限申请的回调。
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PERMISSION_CAMERA_REQUEST_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//允许权限,有调起相机拍照。
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, getphotoUri());
startActivityForResult(intent, TAKE_PHOTO);
//initAccessTokenWithAkSk();
} else {
//拒绝权限,弹出提示框。
Toast.makeText(this, "拍照权限被拒绝", Toast.LENGTH_LONG).show();
}
}
}
通过file获取图片路径
public static String getRealFilePath(final File file ) {
String data = null;
data = file.getAbsolutePath();
return data;
}
拍照的回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case TAKE_PHOTO:
if (resultCode == RESULT_OK) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(pohotouri, "photo/*");
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, pohotouri);
Currency();
// startActivityForResult(intent, CROP_PHOTO); // 启动裁剪程序
}
break;
case CROP_PHOTO:
if (resultCode == RESULT_OK) {
try {
bitmap = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(pohotouri));
Currency();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
}
}
调用百度OCR,识别文字并展示结果,这里应当注意要把获取TextView控件与设置控件内容放在一个函数里,否则会报nullpointexception
public void Currency() {
final StringBuffer sb = new StringBuffer();
// 通用文字识别参数设置
GeneralBasicParams param = new GeneralBasicParams();
param.setDetectDirection(true);
String str=getRealFilePath(file);
param.setImageFile(new File(str));
// 调用通用文字识别服务
OCR.getInstance(this).recognizeGeneralBasic(param, new OnResultListener<GeneralResult>() {
@Override
public void onResult(GeneralResult result) {
// 调用成功,返回GeneralResult对象
for (WordSimple wordSimple : result.getWordList()) {
// wordSimple不包含位置信息
sb.append(wordSimple.getWords());
sb.append("\n");
}
TextView txt = findViewById(R.id.txt);
txt.append(sb.toString()+"\n以上是识别结果");
// json格式返回字符串
// listener.onResult(result.getJsonRes());
}
@Override
public void onError(OCRError error) {
// 调用失败,返回OCRError对象
}
});
}
最后一步
@Override
protected void onDestroy() {
super.onDestroy();
// 释放内存资源
OCR.getInstance(this).release();
}
多内容可以参考
https://blog.csdn.net/k571039838k/article/details/82178410
https://blog.csdn.net/cyyyy_da/article/details/84403714