Android app 接入PaddleOCR

编程入门 行业动态 更新时间:2024-10-25 05:20:31

<a href=https://www.elefans.com/category/jswz/34/1771384.html style=Android app 接入PaddleOCR"/>

Android app 接入PaddleOCR

Android app 接入PaddleOCR

一、 解压文件

资源下载:

解压文件夹,文件目录如下
  • assets:模型资源
  • cpp:c++源码
  • ocr:使用模型需要用到的类
  • OpenCV | PaddleLite :编译和使用模型需要的库

二、 库、模型、cpp文件的设置

1. 将你的项目目录切换至Project视图(以下所有操作都要在project视图下完成)
2. 将OCR下的 “OpenCV” 和 “PaddleLite” 复制至Application-app下,这是编译和使用模型需要用到的库
3. 在app-src-main目录下创建一个assets文件夹,具体方式如下
4. 将OCR下assets中的全部内容复制到app-main-scr-assets下,此时目录结构如图
5. 将OCR下的cpp文件夹复制到app-src-main下,其中存放的是C++功能代码
6. 右键cpp文件夹,选择 “Mark Directory as” - “Sources Root”

三、 代码设置

1. 将OCR下的ocr文件夹复制到项目目录app-src-main-java-com.**(你的包名)下,如图
并将ocr文件下代码路径(包名)修改为自己项目的路径(后面的 “.ocr” 不要去掉)
2. 在app-src-main-res中创建文件夹xml,并新建一个xml文件 “file_paths.xml”
并在 “file_paths.xml” 中添加如下代码,照片权限相关
<?xml version="1.0" encoding="utf-8"?>
<paths><external-files-path name="my_images" path="Pictures" />
</paths>
3. 在 “AndroidManifest.xml” 中<manifest></manifest>之间添加如下带代码
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.CAMERA"/>
并在 <application></application>之间添加如下带代码,注意修改包名
		<!--注意android:authorities中"com.example.myapplication"要改成自己的包名--><providerandroid:name="androidx.core.content.FileProvider"android:authorities="com.example.myapplication.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider>
4. 打开Build.gradle(:app),在android{}中添加如下代码
externalNativeBuild {cmake {path "src/main/cpp/CMakeLists.txtversion "3.10.2"}
}
并在defaultConfig {}中添加如下代码
	externalNativeBuild {cmake {cppFlags "-std=c++11 -frtti -fexceptions -Wno-format"arguments '-DANDROID_PLATFORM=android-23','-DANDROID_STL=c++_shared',"-DANDROID_ARM_NEON=TRUE"}}ndk {// abiFilters "arm64-v8a", "armeabi-v7a"abiFilters   "arm64-v8a", "armeabi-v7a"ldLibs "jnigraphics"}
5. 打开app-src-main-cpp-native.cpp,找到14、59、105行的java入口,修改包名为自己的包名

至此将PaddleOCR植入自己项目的准备工作完成

四、在自己的Activity中使用PaddleOCR功能

注意activity要与ocr文件在同一包下面

1. Activity{}中添加如下代码
    // 1.放在自己的onCreate()前private static final String TAG = "MainActivity";private static final int TAKE_PHOTO_REQUEST_CODE = 1;protected ImageView ivInputImage;protected TextView tvOutputResult;protected String imagePath = "";private String currentPhotoPath;protected Predictor predictor = new Predictor();// 2.重写onResume方法@Overrideprotected void onResume() {super.onResume();boolean settingsChanged = false;//这里要改成自己的初始图片路径String image_path = "images/1.jpg";settingsChanged |= !image_path.equalsIgnoreCase(imagePath);if(settingsChanged){imagePath = image_path;loadModel();}}// 3.重写onActivityResult()方法@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {if (currentPhotoPath != null) {ExifInterface exif = null;try {exif = new ExifInterface(currentPhotoPath);} catch (IOException e) {e.printStackTrace();}int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_UNDEFINED);Log.i(TAG, "rotation " + orientation);Bitmap image = BitmapFactory.decodeFile(currentPhotoPath);image = Utils.rotateBitmap(image, orientation);onImageChanged(image);} else {Log.e(TAG, "currentPhotoPath is null");}}}// 4.重写onRequestPermissionsResult()方法@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) {Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();}}// 5.重写onDestroy()方法@Overrideprotected void onDestroy() {if (predictor != null) {predictor.releaseModel();}super.onDestroy();}// 5.拍照方法(在xml文件里用对应拍照按钮的onclick绑定)// !!其中“MainActivity”改成自己的Activity名,“com.example.myapplication”改成自己的包名public void takePhoto(View v) {if(requestAllPermissions()){Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);if (takePictureIntent.resolveActivity(getPackageManager()) != null) {File photoFile = null;try {photoFile = createImageFile();} catch (IOException ex) {Toast.makeText(MainActivity.this,"Create Camera temp file failed: " + ex.getMessage(), Toast.LENGTH_SHORT).show();}if (photoFile != null) {Uri photoURI = FileProvider.getUriForFile(this,"com.example.myapplication.fileprovider",photoFile);currentPhotoPath = photoFile.getAbsolutePath();takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);startActivityForResult(takePictureIntent, TAKE_PHOTO_REQUEST_CODE);}}}}// 6.判断是否调用权限private boolean requestAllPermissions() {if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA},0);return false;}return true;}// 7.模型相关public void loadModel() {if (onLoadModel()) {onLoadModelSuccessed();}return;}public boolean onLoadModel() {// 初始化predictor// 这里“MainActivity”改成自己的Activityreturn predictor.init(MainActivity.this);}public void onLoadModelSuccessed() {try {if (imagePath.isEmpty()) {return;}Bitmap image = null;if (!imagePath.substring(0, 1).equals("/")) {InputStream imageStream = getAssets().open(imagePath);image = BitmapFactory.decodeStream(imageStream);} else {if (!new File(imagePath).exists()) {return;}image = BitmapFactory.decodeFile(imagePath);}if (image != null && predictor.isLoaded()) {// 输入识别图片predictor.setInputImage(image);runModel();}} catch (IOException e) {// !!"MainActivity"改成自己的ActivityToast.makeText(MainActivity.this, "Load image failed!", Toast.LENGTH_SHORT).show();e.printStackTrace();}}public void runModel() {if (onRunModel()) {onRunModelSuccessed();}}public boolean onRunModel() {return predictor.isLoaded() && predictor.runModel();}// 这里拿到识别结果!!public void onRunModelSuccessed() {//!!这里拿到识别结果outputImage 类型为Bitmap Bitmap outputImage = predictor.outputImage();if (outputImage != null) {ivInputImage.setImageBitmap(outputImage);}//!!这里拿到predictor.outputResult()是识别结果 类型为String  //格式为  1:识别结果1/n//       2:识别结果2/n//       3:识别结果3/ntvOutputResult.setText(predictor.outputResult());tvOutputResult.scrollTo(0, 0);}// 8.图片相关public void onImageChanged (Bitmap image){if (image != null && predictor.isLoaded()) {predictor.setInputImage(image);runModel();}}private File createImageFile() throws IOException {String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());String imageFileName = "JPEG_" + timeStamp + "_";File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);File image = File.createTempFile(imageFileName,  ".bmp",       storageDir   );return image;}
2. 修改页面xml文件

给Activity对应xml文件的拍照按钮添加点击事件,绑定Activity中的takePhoto()方法:

android:onClick="takePhoto"

五、其他配置

1. Settings - Appearance&Behavior - Android SDK - SDK Tools 中 这几项要是已下载的状态
2. Project Structure - SDK Location , 配置自己的sdk、ndk、jdk位置

具体实现可参照项目源代码
下载地址:

更多推荐

Android app 接入PaddleOCR

本文发布于:2024-03-12 16:52:39,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1731964.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Android   app   PaddleOCR

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!