Flutter屏幕捕获插件capture的使用

Flutter屏幕捕获插件capture的使用

© Everial

这是一份使用Everial屏幕捕获插件Capture的最小化示例项目。该插件提供了官方文档识别功能和数据提取功能。它支持所有捕获功能。

关于功能工作的说明

该插件设计用于在移动设备上进行处理。然而,它必须定期访问某些web服务:

  • 应用程序首次使用时
  • 使用情况收集
  • 模型识别更新
  • 配置更新
  • 生命证明测试
  • 对于性能较弱的手机,访问额外的web服务

连接状态检测是自动且透明的。

安装前的准备

请求标识符

SDK初始化需要由Everial提供的用户名和密码。该用户名与嵌入SDK的应用程序包名(iOS、Android)相关联。例如:com.yourcompany.yourapp

测试应用程序已预配置您的标识符。请参阅文件 “home.html”

版本

iOS

插件必须使用Swift版本5进行编译。最低iOS版本为13。

Android

插件支持从SDK版本24开始的Android。

测试应用程序的安装

解压后,在根目录执行以下命令:

flutter pub get

这将导入依赖项。

iOS

  • 在项目目录./example中构建:flutter build ios --no-codesign
  • 在./ios/App中打开 “App.xcworkspace”。
  • 指定开发签名和证书。
  • 在项目的设置信息选项卡中,添加一个条目:“Privacy - Camera Usage Description” 并为用户相机使用提供文本描述。
  • 运行

Android

  • 打开目录./android在Android Studio中。

  • 在应用的 “build.gradle” 文件中,添加Everial Maven仓库和JitPack:

    repositories {
      ...
      maven {
          url 'https://pkgs.dev.azure.com/Everial/Doclab/_packaging/plugins/maven/v1'
          name 'Main_Feed'
      }
      maven {
          url  'https://jitpack.io'
      }   
    }
    
  • 在variables.gradle中,将minSDK版本提高到24以兼容CameraX:

    ext {
      minSdkVersion = 24
      compileSdkVersion = 29
      ...
    }
    

使用方法

该插件在Flutter/Dart中名为 ‘capture’:

import 'package:capture/capture.dart';

它需要添加到 ‘pubspec.yaml’ 文件中:

dependencies:
  flutter:
    sdk: flutter
    git:
        url: [Azure Git地址]

初始化(登录、密码)

SDK必须通过调用 initialize 函数进行初始化(登录、密码)。

第一次使用时,SDK会连接到认证服务器并获取授权应用包名。除非完成此初始验证,否则SDK无法使用。

返回对象

无论哪种情况,都会返回一个JSON痕迹。JSON是一个RTRLogs对象:

{
    RTRLogs :[RTRLog],
    Severity : int    
}

RTRLog
{  
    type : case info=0,warning=1,error=2,fatal=3
    caller:String,
    shortDescription: String,
    longDescription: String
}

日志是累积性的,需要检查 severity 字段以了解最严重的错误。

错误类型分类:
  • 0: 信息:用于跟踪处理过程
  • 1: 警告:遇到异常但不影响分析流程。主要是应用程序离线模式
  • 2: 错误:在处理分析过程中发生错误(捕获、OCR、验证)。这不会影响后续分析或捕获继续
  • 3: 致命:阻止错误。SDK无法运行。主要由于身份验证失败或初始化分析不可行

任何类型的3(致命)错误使分析无法使用。RTRLog表是信息性的。

示例:
try {
  final res = await Capture().onInitialize(login, password);
  if (res != null) {
    // 处理结果
  }
} on PlatformException catch (err) {
  // 处理错误
}

当初始化成功时:

{
    "RTRLogs":[
        {
            "caller":"<EverialRT.ConfigurationManager: 0x102f129c0>",
            "longDescription":"remote config loaded for: bundle",
            "type":0,
            "shortDescription":"remote config loaded"
        },
        {
            "caller":"<EverialRT.ConfigurationManager: 0x102f129c0>",
            "longDescription":"remote config loaded for: schema",
            "type":0,
            "shortDescription":"remote config loaded"
        }
    ],
    "severityFlag":0
}

断网示例:

{
    "RTRLogs":[
        {
            "caller":"<EverialRT.ConfigurationManager: 0x1056052c0>",
            "longDescription":"Error while authenticating: Optional(Error Domain=NSURLErrorDomain Code=-1009 \"The Internet connection appears to be offline.\" UserInfo={NSUnderlyingError=0x282b57870 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 \"(null)\" UserInfo={_kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=https:\/\/auth.devlab.everial.com\/auth\/realms\/quota\/protocol\/openid-connect\/token, NSErrorFailingURLKey=https:\/\/auth.devlab.everial.com\/auth\/realms\/quota\/protocol\/openid-connect\/token, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=50, NSLocalizedDescription=The Internet connection appears to be offline.})",
            "type":2,
            "shortDescription":"Error while authenticating"
        }
    ],
    "severityFlag":2
}

第一次使用时,如果没有启用互联网连接,初始化可能会返回这种响应:

{
    "caller":"<EverialRT.RTR: 0x133e03af0>:processHiRes",
    "longDescription":"User or SDK not granted for this application",
    "type":3,
    "shortDescription":"User or SDK not granted"
}

process({}, success, error)

该函数在父视图中实例化一个捕获视图并启动扫描。可以触摸视图来中断分析。

分析可以在不重新初始化的情况下重新启动。当捕获完成(匹配或中断)时,视图将从父视图中删除。

示例:
dynamic result = await Capture().onProcess();

result 包含数据:SUCCESS: JSON: 提取的文档数据 result 包含错误 / try-catch: ERROR: 错误消息

响应

响应的 content-type 为:application/json; charset=utf-8 响应结构如下:

  • subscriber -> 相当于文档间的级别,即文件夹概念
  • 一个文档数组 -> 一个文档: CNI, JUDO
  • 每个文档包含一个页面数组 -> 文档的页面,例如正反面

每个级别都有结构:

result -> "errors", "descriptions", "value" + "fields" at the page level

如果失败,错误日志将返回图像:

{
    "caller":"analyse",
    "longDescription":"base64 image url encoded",
    "type":0,
    "shortDescription":"Document"
}
使用响应进行操作

响应形式为:

{value:"JSON_DOC_STRING"}

因此,需要这样处理:

try {
  dynamic result = await Capture().onProcess();
  // 等效于:json.decode(docToFormat)['value'];
  dynamic resValue = _getDocValue(result);

  if (resValue != '') {
    // 处理数据
  } else {
    throw Exception("Nothing to add.");
  }
} on PlatformException catch (err) {
  // 处理错误
}

consolidate({array of json documents}, success, error)

该方法允许对多个文档进行一致性检查。

await Capture().onConsolidate({ documents: docs })

iOS

如果提供的数组为空,应用程序将比较已分析的文档,即根据先前分析列表。列表构成方式为LIFO:相同类型的每个文档都会覆盖之前的文档。 然而,在客户端应用程序管理文档的情况下,可以在应用程序客户端存储已分析的文档,然后请求验证并重新提供适当的文档。 在这种情况下,文档的json需要提供在一个数组中。

注意:在这种情况下,分析引擎的列表将被提供的列表替换。

Android

应用程序负责管理已分析的文档。插件不保留任何先前分析的痕迹。 已分析的文档需要在应用程序客户端存储,并可以请求验证那些认为合适的文档。这些文档应在接收分析并存储在数组中的JSON字符串中重新提供。

响应

响应的 content-type 为:application/json; charset=utf-8 验证字段的结构与 process 的相同,但在 <strong>subscriber</strong> 键中有额外的控制。

analyze({ fileuri: file }, success, error)

该方法可以在不调用捕获函数的情况下实现文档分析。在这种情况下,假设应用程序支持文件收集。需要提供文件在设备上的路径。响应与 process 相同。 接受的类型为 image/* 和 application/pdf。 对于PDF,只分析第一页。

await Capture().onAnalyze({ fileuri: file })

Android

预期的字符串类型为Uri (android.net.Uri: Uri.toString())

iOS:

预期的字符串类型为URL (url.absolutestring())

selfie({ baseimage: extractedPhoto }, success, error)

await Capture().onSelfie({ baseimage: extractedPhoto })

该方法执行两个检查:

  • 将提供的参数 “imgBase” (base64图像) 与用户的面部进行比较
  • 生命证明测试

调用此功能时,摄像头会被触发,用户被要求将脸部放在框内几秒钟。 在iOS上,体验略有不同,会显示地标。 分析只需几秒钟,无需任何用户场景。

响应类型为json,只有一个键:

{"valid": "true" | "false"}

注意:应用程序记录所有与之前注册的文档相关的照片。

SSL Pinning

插件可以执行“中间人”检查。 为此,Everial会在您的用户级别激活此参数。

{"RTRContext" : "2.3.0:capsule-dev", "caller" : "com.everial.rtr.Configuration", "longDescription" : "SSL pinning enabled", "shortDescription" : "SSL pinning enabled", "type" : 0}

如果启用了检查,插件将在初始化时确保展示的公钥证书确实是Everial的。

初始化会返回错误。

此错误不是阻止性的,应用程序可以选择是否停止应用。

{"RTRContext" : "2.3.0:capsule-dev", "caller" : "com.everial.rtr.Configuration", "longDescription" : "user=capsule-dev,pub=CBSA08mY+VfrZrjVgkDDpFbz6JBBavdW6TPgbCYde58=, received certificate: Certificate pinning failure!\n  Peer certificate chain:\n    sha256/tJqnS+/9e9HeWUtNxnTbdpfA0oCOC9ka30l8fGiE4p0=: CN=k8s.doclab.fr\n    sha256/Ns1wdAOg3MUrrOICXWYlMXelaJL9M6n/Y9nuYfZawsM=: C=NZ,ST=Auckland,L=Auckland,O=XK72 Ltd,OU=https://charlesproxy.com/ssl,CN=Charles Proxy CA (4 Nov 2021\\, MacBook-Pro-de-Sebastien.local)\n  Pinned certificates for log.k8s.doclab.fr:\n    sha256/CBSA08mY+VfrZrjVgkDDpFbz6JBBavdW6TPgbCYde58=", "shortDescription" : "Error while pinning certificate", "type" : 2}

更多关于Flutter屏幕捕获插件capture的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter屏幕捕获插件capture的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用capture插件进行屏幕捕获的代码示例。请注意,capture插件的具体实现可能依赖于某个第三方库,因为Flutter本身并没有一个名为capture的官方插件。在这里,我将使用一个假定的第三方插件screen_capture来演示这一过程(请注意,实际使用时你需要替换为真实存在的插件)。

首先,你需要在pubspec.yaml文件中添加屏幕捕获插件的依赖项(假设插件名为screen_capture):

dependencies:
  flutter:
    sdk: flutter
  screen_capture: ^x.y.z  # 替换为实际的版本号

然后,运行flutter pub get来安装该依赖项。

接下来,在你的Flutter项目中,你可以按照以下步骤使用屏幕捕获功能:

  1. 导入插件

在你的Dart文件中导入插件:

import 'package:screen_capture/screen_capture.dart';
  1. 请求权限(如果需要):

某些平台(如Android)可能需要额外的权限来捕获屏幕。你需要在AndroidManifest.xml中声明这些权限,并在运行时请求它们。以下是一个在Android上请求权限的示例(注意,具体实现可能因插件而异):

import 'package:permission_handler/permission_handler.dart';

Future<void> requestPermissions() async {
  if (await Permission.storage.status != PermissionStatus.granted) {
    Map<Permission, PermissionStatus> statuses = await Permission.request([
      Permission.storage,
    ]);

    if (statuses[Permission.storage] != PermissionStatus.granted) {
      // 权限被拒绝,处理逻辑
      return;
    }
  }
}

请确保在pubspec.yaml中也添加了permission_handler依赖项。

  1. 捕获屏幕

使用插件提供的API来捕获屏幕:

void captureScreen() async {
  try {
    // 捕获屏幕并获取文件路径
    String filePath = await ScreenCapture.capture();
    
    // 显示或处理捕获的屏幕截图
    print("Screenshot saved to: $filePath");
    // 例如,你可以使用Image.file(File(filePath))来显示截图
  } catch (e) {
    // 处理错误
    print("Failed to capture screenshot: $e");
  }
}
  1. 在按钮点击事件中调用捕获函数

在你的UI中,添加一个按钮来触发屏幕捕获:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Screen Capture Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              await requestPermissions();  // 请求权限(如果需要)
              captureScreen();  // 捕获屏幕
            },
            child: Text('Capture Screen'),
          ),
        ),
      ),
    );
  }
}

请注意,上述代码是一个简化的示例,实际使用中可能需要处理更多的细节,如权限请求的UI、错误处理、以及在不同平台上的兼容性等。此外,由于screen_capture是一个假定的插件名称,你需要替换为实际存在的屏幕捕获插件,并根据其文档进行相应的调整。

回到顶部