47 lines
1.3 KiB
Dart
47 lines
1.3 KiB
Dart
|
|
import '../models/note.dart';
|
||
|
|
import '../models/pen_tool.dart';
|
||
|
|
import 'database_service.dart';
|
||
|
|
import 'ocr_engine.dart';
|
||
|
|
import 'stroke_rasterizer.dart';
|
||
|
|
|
||
|
|
/// Runs OCR locally: typed text from strokes + handwriting via platform OCR.
|
||
|
|
class OcrService {
|
||
|
|
/// Extract searchable text from [note] and merge into the local FTS index.
|
||
|
|
Future<void> processNote(Note note) async {
|
||
|
|
final parts = <String>[];
|
||
|
|
|
||
|
|
for (final stroke in note.strokes) {
|
||
|
|
if (stroke.tool == PenTool.text &&
|
||
|
|
stroke.textContent != null &&
|
||
|
|
stroke.textContent!.trim().isNotEmpty) {
|
||
|
|
parts.add(stroke.textContent!.trim());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
final handwritingStrokes = note.strokes
|
||
|
|
.where(
|
||
|
|
(s) =>
|
||
|
|
s.tool != PenTool.eraser &&
|
||
|
|
s.tool != PenTool.text &&
|
||
|
|
s.points.isNotEmpty,
|
||
|
|
)
|
||
|
|
.toList();
|
||
|
|
|
||
|
|
if (handwritingStrokes.isNotEmpty) {
|
||
|
|
final png = await StrokeRasterizer.render(handwritingStrokes);
|
||
|
|
if (png != null) {
|
||
|
|
final recognized = await OcrEngine.recognizeImage(png);
|
||
|
|
if (recognized != null && recognized.isNotEmpty) {
|
||
|
|
parts.add(recognized);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
final combined = parts.join(' ').trim();
|
||
|
|
if (combined.isEmpty) return;
|
||
|
|
|
||
|
|
final db = await DatabaseService.getInstance();
|
||
|
|
await db.appendOcrToFts(note.id, combined);
|
||
|
|
}
|
||
|
|
}
|