FlutterアプリのカメラフィードにほぼリアルタイムのOCRを実装したいと思います。そのためには、カメラのデータにスピーディーにアクセスしたいと思います。私が知る限り、私には2つのオプションがあり、両方でロードブロッキングが発生しています。
CameraPreview
をその周りに配置してRepaintBoundary
を作成し、boundary.toImage()
を呼び出して、RenderRepaintBoundary
のスクリーンショットを撮ります。このメソッドの問題は、.toImageメソッドは、境界でペイントされたウィジェットのみをキャプチャし、カメラのプレビューからのデータはキャプチャしないように見えることです。ここで説明する問題と同様: https://github.com/flutter/flutter/issues/17687
サンプルドキュメントと同様に、Camera 0.2.1のcontroller.takePicture(filePath)
を使用して画像をキャプチャします。ここでの問題は、画像が利用可能になるまでに非常に長い時間がかかることです(2〜3秒)。これは、ファイルがキャプチャ時にディスクに保存され、その後ファイルから再度読み取る必要があるためと考えられます。
キャプチャ後に画像情報に直接アクセスして、前処理やOCRなどを行う方法はありますか?
「ほぼリアルタイムのOCR」の場合、CameraController#startImageStream
コード例
import 'package:camera/camera.Dart';
import 'package:flutter/foundation.Dart';
import 'package:flutter/material.Dart';
void main() => runApp(MaterialApp(home: _MyHomePage()));
class _MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<_MyHomePage> {
dynamic _scanResults;
CameraController _camera;
bool _isDetecting = false;
CameraLensDirection _direction = CameraLensDirection.back;
@override
void initState() {
super.initState();
_initializeCamera();
}
Future<CameraDescription> _getCamera(CameraLensDirection dir) async {
return await availableCameras().then(
(List<CameraDescription> cameras) => cameras.firstWhere(
(CameraDescription camera) => camera.lensDirection == dir,
),
);
}
void _initializeCamera() async {
_camera = CameraController(
await _getCamera(_direction),
defaultTargetPlatform == TargetPlatform.iOS
? ResolutionPreset.low
: ResolutionPreset.medium,
);
await _camera.initialize();
_camera.startImageStream((CameraImage image) {
if (_isDetecting) return;
_isDetecting = true;
try {
// await doSomethingWith(image)
} catch (e) {
// await handleExepction(e)
} finally {
_isDetecting = false;
}
});
}
Widget build(BuildContext context) {
return null;
}
}
この機能は https://github.com/flutter/plugins に統合されましたが、十分に文書化されていませんでした。
参照: