本文转载自好基友upuptop:https://blog.csdn.net/pyfysf/article/details/77455330
效果图:
如下为文章正文:
最近有个小项目使用到了OCR技术,顺便到网上搜索了一下,大家都在使用百度的API,所以我就调用了百度的接口。
在使用的过程中也是遇到了各种各样的错误,比如 TOKEN ERROR 了等等。
一、注册登录百度云平台
首先注册登陆百度账号,点击这里跳转到百度API接口首页:
https://login.bce.baidu.com/?account=&redirect=http%3A%2F%2Fconsole.bce.baidu.com%2F
注册登陆之后在左侧的 "产品服务" 找到 “文字识别”:
创 "文字识别" 建项目:
创建项目后,在应用类表获取项目的:API Key、Secret Key
粘贴到项目 Demo 中:
二、配置SDK,查看文档调用接口
文档地址:https://cloud.baidu.com/doc/OCR/OCR-Android-SDK.html#.E6.95.B0.E6.8D.AE.E6.8E.A5.E5.8F.A3
博主使用的是Android平台的SDK,根据步骤进行SDK工程配置。
配置完工程之后博主就很惊喜的去调用方法进行写代码了。
但是,logcat总是报错。说获取token失败,packname错误或者AK和SK错误。
这里我就很是纳闷,我根本没有设置项目的包名,并且我的AK和SK是正确的。大家有知道解决方法,求大神在评论区指教博主,博主在这里叩谢。
然后经过我查询资料,我选择请求API,从而不去调用百度封装的方法。
三、实现代码片段(不提供xml布局文件)
下面将贴一些代码片段。不想看代码片段的直接下滑到最后下载 Demo 源码。
博主是打开相机拍一张照片进行扫描实现OCR识别文字,百度的API可以接受本地图片的路径,或者网络上的图片URL也可以进行OCR文字扫描。
我用到了百度提供的UI,在SDK里面导入到项目里面就可以了。
/**
* 打开相机
*/
public void openCameraByBaidu() {
Intent intent = new Intent(GuideActivity.this, CameraActivity.class);
intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH,
FileUtil.getSaveFile(getApplication()).getAbsolutePath());
intent.putExtra(CameraActivity.KEY_CONTENT_TYPE,
CameraActivity.CONTENT_TYPE_GENERAL);
startActivityForResult(intent, OPEN_CAMERA_OK);
}
拍照之后获取照片的保存路径:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
##判断请求码是否是请求打开相机的那个请求码
if (requestCode == OPEN_CAMERA_OK && resultCode == RESULT_OK) {
String photoPath = FileUtil.getSaveFile(this).getAbsolutePath();
checkData(photoPath);
}
}
核心代码在这里!!
请求百度文字识别API,进行图片OCR识别,我用的是 xUtils3.0 请求的网络。也可以使用HTTPConnection 发起 get 请求,如下是参考代码:
/**
* 请求百度API接口,进行获取数据
*
* @param filePath
*/
private void checkData(String filePath) {
try {
/**把图片文件转换为字节数组**/
byte[] imgData = FileUtil.readFileByBytes(filePath);
/**对字节数组进行Base64编码**/
String imgStr = Base64Util.encode(imgData);
final String params = URLEncoder.encode("image", "UTF-8") + "=" + URLEncoder.encode(imgStr, "UTF-8");
RequestParams entiry = new RequestParams(ConstantValue.BAIDU_TOKEN_URL);
x.http().get(entiry, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(final String result) {
Gson gson = new Gson();
TokenInfo tokenInfo = gson.fromJson(result, TokenInfo.class);
final String access_token = tokenInfo.getAccess_token();
new Thread() {
public void run() {
public static final String BAIDU_TOKEN_URL
= "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + 你在百度控制台创建的AK+ "&client_secret=" +
你在百度控制台创建的SK;
String resultStr = HttpUtil.post(ConstantValue.BAIDU_INTER_URL, access_token, params);
Log.e("MainActivity", "MainActivity onSuccess()" + resultStr);
Message msg = Message.obtain();
msg.obj = resultStr;
msg.what = PRESER_IMG_OK;
handler.sendMessage(msg);
}
}.start();
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
});
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
解析数据,官方返回的是一个json串。所以我们进行解析数据
private static Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case PRESER_IMG_OK:
String data = (String) msg.obj;
preserData(data);
break;
}
}
};
private static void preserData(String data) {
Gson gson = new Gson();
WordInfo wordInfo = gson.fromJson(data, WordInfo.class);
if(wordInfo.getError_code() != null) {
if (wordInfo.getError_code() == 17 || wordInfo.getError_code() == 19 || wordInfo.getError_code() == 18) {
Toast.makeText(MyApp.getContext(), "请求量超出限额", Toast.LENGTH_SHORT).show();
return;
}
}
if (wordInfo.getWords_result() == null || wordInfo.getWords_result_num() < 0 || wordInfo.getWords_result().size() == 0) {
Toast.makeText(MyApp.getContext(), "文字扫描识别失败,请重试", Toast.LENGTH_SHORT).show();
return;
}
wordInfo.getWords_result() ;//这里面就是扫描出来的数据
}
FileUtil
public static File getSaveFile(Context context) {
File file = new File(context.getFilesDir(), "pic.jpg");
return file;
}
/**
* 根据文件路径读取byte[] 数组
*/
public static byte[] readFileByBytes(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
throw new FileNotFoundException(filePath);
} else {
ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(file));
short bufSize = 1024;
byte[] buffer = new byte[bufSize];
int len1;
while (-1 != (len1 = in.read(buffer, 0, bufSize))) {
bos.write(buffer, 0, len1);
}
byte[] var7 = bos.toByteArray();
return var7;
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException var14) {
var14.printStackTrace();
}
bos.close();
}
}
}
}
HttpUtils
/**
* http 工具类
*/
public class HttpUtil {
public static String post(String requestUrl, String accessToken, String params) {
try {
String generalUrl = requestUrl + "?access_token=" + accessToken;
URL url = new URL(generalUrl);
/**打开和URL之间的连接**/
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
/**设置通用的请求属性**/
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setDoInput(true);
/**得到请求的输出流对象**/
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes(params);
out.flush();
out.close();
/**建立实际的连接**/
connection.connect();
/**获取所有响应头字段**/
Map<String, List<String>> headers = connection.getHeaderFields();
/**遍历所有的响应头字段**/
for (String key : headers.keySet()) {
System.out.println(key + "--->" + headers.get(key));
}
/**定义 BufferedReader输入流来读取URL的响应**/
BufferedReader in = null;
if (requestUrl.contains("nlp"))
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "GBK"));
else
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String result = "";
String getLine;
while ((getLine = in.readLine()) != null) {
result += getLine;
}
in.close();
System.out.println("result:" + result);
return result;
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
Base64Util
/**
* Base64 工具类
*/
public class Base64Util {
private static final char last2byte = (char) Integer.parseInt("00000011", 2);
private static final char last4byte = (char) Integer.parseInt("00001111", 2);
private static final char last6byte = (char) Integer.parseInt("00111111", 2);
private static final char lead6byte = (char) Integer.parseInt("11111100", 2);
private static final char lead4byte = (char) Integer.parseInt("11110000", 2);
private static final char lead2byte = (char) Integer.parseInt("11000000", 2);
private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
public Base64Util() {
}
public static String encode(byte[] from) {
StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3);
int num = 0;
char currentByte = 0;
int i;
for (i = 0; i < from.length; ++i) {
for (num %= 8; num < 8; num += 6) {
switch (num) {
case 0:
currentByte = (char) (from[i] & lead6byte);
currentByte = (char) (currentByte >>> 2);
case 1:
case 3:
case 5:
default:
break;
case 2:
currentByte = (char) (from[i] & last6byte);
break;
case 4:
currentByte = (char) (from[i] & last4byte);
currentByte = (char) (currentByte << 2);
if (i + 1 < from.length) {
currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6);
}
break;
case 6:
currentByte = (char) (from[i] & last2byte);
currentByte = (char) (currentByte << 4);
if (i + 1 < from.length) {
currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4);
}
}
to.append(encodeTable[currentByte]);
}
}
if (to.length() % 4 != 0) {
for (i = 4 - to.length() % 4; i > 0; --i) {
to.append("=");
}
}
return to.toString();
}
}
这样就可以实现了。
本文的案例源码下载地址在这里哦!!!!
https://download.csdn.net/download/pyfysf/10406761
有问题可以加博主QQ哦。337081267
18年专科毕业后一度迷茫,创建了一个用来记录自己成长的公众号,感兴趣的小伙伴可以关注一下~