基于飞浆paddle的Android硬字幕提取 — 二

文章目录

  • 基于飞浆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进行处理,非常感谢!

上一篇 2022年4月5日
下一篇 2022年4月5日

相关推荐