How To

Use Flutter & Dart

Using RustO! OCR engine in Flutter mobile, desktop, and pure Dart applications via FFI.

RustO! provides both pure Dart FFI bindings (rusto) and a native Flutter plugin (rusto_flutter) with Android and iOS platform integration.

Installation

For Flutter Projects

flutter pub add rusto_flutter

For Pure Dart / Server Projects

dart pub add rusto

1. Engine Initialization

Initialize the engine by supplying model weights and dictionary configuration:

import 'package:rusto/rusto.dart';

final config = '''
{
  "detection": { "model_path": "assets/models/PPOCR_v6/det.rten" },
  "recognition": { "model_path": "assets/models/PPOCR_v6/rec.rten", "dict_path": "assets/models/PPOCR_v6/dict.txt" }
}
''';

final engine = RustO.initialize(config);

2. Text Recognition

Structured Recognition

// Run recognition on local image file
final results = engine.detectTextFile('receipt.jpg');

for (final line in results) {
  print('[${line.score.toStringAsFixed(2)}] ${line.text}');
  print('  Frame: left=${line.frame.left}, top=${line.frame.top}, w=${line.frame.width}, h=${line.frame.height}');
}

// Clean up native resources when done
engine.close();

From Uint8List Image Bytes

import 'dart:io';

final bytes = File('document.png').readAsBytesSync();
final results = engine.detectTextData(bytes);

3. Spatial Layout Reconstruction

final spatialText = engine.detectTextFileSpatial('invoice.png');
print('--- Spatial Document Layout ---');
print(spatialText);

4. Best Practices in Flutter Tests

When writing testWidgets that interact with native FFI loops, always load fixture files using synchronous file operations (File(path).readAsBytesSync()) rather than asynchronous await File(path).readAsBytes(). This avoids event loop scheduling stalls within Flutter's FakeAsync test zones.