文章目录
- 基于飞浆Paddle的Android字幕实时提取
-
- 介绍
- 一,对接PaddleLite编译相关文件
- 二,新建无障碍服务
- 三,前台服务的辅助服务类
- 四,截屏的功能实现
- 五,文字识别
- 六,无障碍服务的手势
- 七,工具类
- 八,MainActivity的实现
-
-
-
- 总结
- 软件架构
- 使用说明
-
-
- 九,资源文件
- 工作心得
基于飞浆Paddle的Android字幕实时提取
介绍
本项目是给盲人提供的一款看电影的实时英文字幕读取的软件;主要采用的技术:
MediaProjection截取屏幕 + AccessibilityService监听手势 + 开源OCR飞浆Paddle + 进程间通信 + 讯飞TTS语音合成
一,对接PaddleLite编译相关文件
1,下载paddle官 的相关demo
官 文档
https://github.com/PaddlePaddle/PaddleOCR
2,配置AndroidStudio的NDK
- 把相关文件拷贝到自己的项目后,下载相关NDK,MARK用来编译我们拷贝的文件
- 主要文件:
- 1 OpenCV
- 2 PaddleLite
- 将1和2文件放在项目app包之下
- 3 cpp
- 将3放在app/src/main您的包名下
- 4 assets
- 将4放在src/main之下 并设置为source root(选中文件右键Mark dir as)
- 5 java文件包名ocr
3,下载NDK和MARK
- 下载相关匹配的NDK这里就不多说了
- 配置您的build.gradle文件/参考官方demo的相同文件
- 修改Predictor.java文件的相关方法,使他适合您自己使用
二,新建无障碍服务
- 我这里主要实现了两个方法
-
第一个函数主要是实时监测手机横屏或者竖屏
-
第二个函数就是监测我们的手势
- 当我们在屏幕上执行(先下后上手势)时此onGesture函数会执行,我这里由于需求的原因需要检测横竖屏,竖屏状态下不执行。
-
第二个函数如何配置执行
- 1在无障碍描述文件添加允许手势操作
- android:accessibilityFlags=“flagReportViewIds|flagIncludeNotImportantViews|flagRequestTouchExplorationMode|flagRequestFingerprintGestures”
- 这是我的全部标记 因为我不仅需要监测手势,还需要监测包名等其他的操作
- 注意:
- 这两句将会非常重要
-
全部如下
三,前台服务的辅助服务类
public class MediaProjrctService extends Service implements ImageReader.OnImageAvailableListener { private VirtualDisplay virtualDisplay; private MediaProjection mediaProjection; private Predictor predictor; private TtsUtils ttsUtils; private Activity activity; private int densityDpi; private Context context; public Handler handler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(@NonNull Message msg) { if (msg.what == 0) { startScreenCapture(); }} }; @Override public void onCreate() {context = getApplicationContext();super.onCreate();Notification notification = createForegroundNotification();int NOTIFICATION_ID = 1;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION);} else { startForeground(NOTIFICATION_ID, notification);}registerReceivers(); } @Override public void onDestroy() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { stopForeground(STOP_FOREGROUND_REMOVE);} else { stopForeground(true);}stopScreenCapture();ttsUtils.cancleSpeech();unregisterReceiver(timerRecivier);super.onDestroy(); } @Override public int onStartCommand(Intent intent, int flags, int startId) {Activity activity = AppUtils.getActivity();MediaProjection mediaProjection = AppUtils.getMediaProjection();if (activity != null && mediaProjection != null) { this.activity = activity; this.mediaProjection = mediaProjection; this.densityDpi = activity.getResources().getDisplayMetrics().densityDpi; predictor = Predictor.getInstace(); predictor.init(activity, AppUtils.assetModelDirPath, AppUtils.assetlabelFilePath); ttsUtils = TtsUtils.initSpeech(activity);}return super.onStartCommand(intent, flags, startId); } private int screenW; private int screenH; private int cenScreenW; private Bitmap bitmap; public void startScreenCapture() {if (mediaProjection != null) { screenW = AppUtils.getScreenW(activity); screenH = AppUtils.getScreenH(activity); @SuppressLint("WrongConstant") ImageReader mImageReader = ImageReader.newInstance(screenW, screenH, 0x1, 1); mImageReader.setOnImageAvailableListener(MediaProjrctService.this, null); virtualDisplay = mediaProjection.createVirtualDisplay("ScreenCapture", screenW, screenH, densityDpi,DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null);} } @Override public void onImageAvailable(ImageReader reader) {Image image = reader.acquireNextImage();if (image != null) { final Image.Plane[] planes = image.getPlanes(); if (planes.length > 0) { ByteBuffer buffer = planes[0].getBuffer(); //每个像素的间距 int pixelStride = planes[0].getPixelStride(); //总的间距 int rowStride = planes[0].getRowStride(); int rowPadding1 = rowStride - pixelStride * screenW; if (bitmap == null) {bitmap = Bitmap.createBitmap((screenW + (rowPadding1 / pixelStride)), screenH, Bitmap.Config.ARGB_8888); } try {bitmap.copyPixelsFromBuffer(buffer);recognitionText(bitmap); } catch (Exception e) {e.printStackTrace(); } image.close(); stopScreenCapture(); }} } private int textH; private int textY; private String text = ""; public void recognitionText(Bitmap bitmap) {声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!