pp_ocr 0.3.2
pp_ocr: ^0.3.2 copied to clipboard
Flutter plugin for offline OCR using PP-OCRv6 (PaddleOCR) with ONNX Runtime C++ inference. Supports text detection and recognition on Windows and Linux.
pp_ocr #
English | 简体中文
A Flutter plugin for offline OCR (Optical Character Recognition) on Windows and Linux, powered by PaddleOCR's PP-OCRv6 models and ONNX Runtime.
Features #
- Offline OCR — No internet connection required. All inference runs locally.
- Dual Backend — Uses
dart:ffiby default for low-latency direct native calls, with automatic fallback toMethodChannel. - Text Detection — DB (Differentiable Binarization) based text detection.
- Text Recognition — CRNN + CTC based text recognition with support for Chinese, English, and 18,000+ characters.
- Unicode Path Support — Correctly handles non-ASCII file paths (Chinese, Japanese, etc.) on Windows.
- Bundled ONNX Runtime — ONNX Runtime is included, no download required. OpenCV is resolved via
find_package(setOpenCV_DIR). - Bounding Box Overlay — Returns detection boxes with recognized text and confidence scores.
Platform Support #
| Platform | Support |
|---|---|
| Windows | ✅ |
| Linux | ✅ |
| Android | ❌ |
| iOS | ❌ |
| macOS | ❌ |
Requirements #
Windows:
- Flutter >= 3.0.0
- Windows 10 or later
- Visual Studio 2022 with CMake support
Linux:
- Flutter >= 3.0.0
- GTK 3 development headers:
sudo apt install libgtk-3-dev - CMake / clang toolchain:
sudo apt install cmake clang ninja-build - OpenCV development package:
sudo apt install libopencv-dev(4.x recommended) - ONNX Runtime: no official apt package on Ubuntu. Download the prebuilt
tarball from Microsoft's GitHub
Releases
(
onnxruntime-linux-x64-<ver>.tgz), then either place itsinclude/andlib/underlinux/third_party/onnxruntime/, or pass-DONNXRUNTIME_ROOT=<path>via yourexample/linux/CMakeLists.txt.
One-shot ONNX Runtime fetch (for networks that cannot reach GitHub) #
If github.com times out (common in mainland China), this repo ships
tool/setup_linux_deps.sh. It downloads the equivalent onnxruntime wheel
from a PyPI mirror, extracts libonnxruntime.so.<ver> into
linux/third_party/onnxruntime/, and creates the libonnxruntime.so /
libonnxruntime.so.1 SONAME symlinks the linker requires.
bash tool/setup_linux_deps.sh # defaults to ORT 1.20.1
ORT_VERSION=1.17.0 bash tool/setup_linux_deps.sh
Then simply:
cd example && flutter run -d linux
Crash after picking a file on Linux (Impeller / Mesa driver) #
On some integrated GPUs — notably Loongson GF (PCI vendor 4c54) — the bundled Mesa driver gf_dri.so has a null-pointer bug that Flutter's default Impeller OpenGLESSDF backend triggers when a GTK file dialog opens/closes. Symptom: the example's pickImage() returns the chosen path but the app crashes right after (Lost connection to device). Kernel log:
kernel: pp_ocr_example[...]: segfault at 2 in gf_dri.so
The plugin already mitigates this: pickImage prefers GtkFileChooserNative, which on systems with xdg-desktop-portal delegates the picker to a separate process (no GL in our process). If you still hit it, use one of these workarounds:
# Option A: force software rasterization (simplest)
LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=llvmpipe flutter run -d linux
# Option B: force X11 backend (helps on some Wayland compositors)
GDK_BACKEND=x11 flutter run -d linux
# Option C: bake the switch into the app. At the top of
# example/linux/runner/main.cc, before any GTK calls:
g_setenv("LIBGL_ALWAYS_SOFTWARE", "1", /*overwrite=*/FALSE);
To sanity-check the whole pipeline headlessly (no dialog, no mouse), the example ships a self-test triggered by env vars:
PP_OCR_SELFTEST_IMAGE=/path/to/your.jpg \
PP_OCR_PICKIMAGE_FAKE_PATH=/path/to/your.jpg \
PP_OCR_SELFTEST_VIA_PICK=1 \
LIBGL_ALWAYS_SOFTWARE=1 \
flutter run -d linux
# Look for [SELFTEST] step 1→5 followed by ALL STEPS PASSED in the log.
Note: ONNX Runtime 1.20.1 is bundled with this plugin (
windows/third_party/). No download or manual setup is required.The bundled files include:
onnxruntime.dll/onnxruntime.lib/ headers — ONNX Runtime inference engineOpenCV is not bundled on Windows anymore (the former bundled
opencv_world490binaries were removed — every build now goes throughfind_package(OpenCV)). Point CMake at your OpenCV installation via-DOpenCV_DIR=<path-to-OpenCVConfig.cmake>or theOpenCV_DIRenvironment variable. For cross-compile scenarios, a static OpenCV built with the same toolchain is recommended (it links statically, so no DLL ships with the app). On Linux, installlibopencv-devor setOpenCV_DIRlikewise.
Installation #
Add this to your pubspec.yaml:
dependencies:
pp_ocr: ^0.3.2
Model Files #
Model files are not included in the pub package or the git repository
(they total ~77 MB — too large to ship; the plugin itself needs none of them,
since you pass model paths to initialize() yourself).
Download the PP-OCRv6 ONNX models and place them in a model/ directory:
model/
├── det.onnx # Text detection model
├── inference.onnx # Text recognition model
└── ppocr_v6_dict.txt # Character dictionary (18,708 entries)
- Pre-converted copies: grab them from this repo's
GitHub Releases
(
model.zipattachment). - Convert yourself: models can be obtained from PaddleOCR and converted to ONNX format using Paddle2ONNX.
The bundled
example/app auto-detectsmodel/next to the repo root (or beside the executable) — the local dev layout stays unchanged.
Usage #
import 'package:pp_ocr/pp_ocr.dart';
final ocr = PaddleOcr();
// Initialize with model paths
await ocr.initialize(
detModelPath: 'path/to/det.onnx',
recModelPath: 'path/to/inference.onnx',
dictPath: 'path/to/ppocr_v6_dict.txt',
);
// Recognize text from an image file
final results = await ocr.recognizeImage('path/to/image.png');
for (final result in results) {
print('Text: ${result.text}');
print('Confidence: ${result.confidence}');
print('Box: ${result.box}');
}
// Release native resources when done
ocr.dispose();
See the example app for a complete demo with image picker and visual box overlay.
Architecture #
The plugin supports two backends:
FFI (Default) #
- C++ engine compiled as DLL with C API (
pp_ocr_ffi.h) - Dart calls native functions directly via
dart:ffi - Lower latency, no serialization overhead
- Automatic fallback to MethodChannel if DLL not found
MethodChannel (Fallback) #
- Traditional Flutter plugin architecture via
MethodChannel('paddle_ocr') - Used when FFI DLL is unavailable
┌──────────────────────────────────────────────┐
│ Dart (pp_ocr.dart) │
│ │ │
│ ┌──────────────┴──────────────┐ │
│ │ PaddleOcrPlatform │ │
│ │ (interface) │ │
│ └──────┬──────────────┬───────┘ │
│ │ │ │
│ ┌──────────▼──┐ ┌───────▼────────┐ │
│ │ FfiPaddleOcr│ │MethodChannel │ │
│ │ (default) │ │PaddleOcr │ │
│ │ dart:ffi │ │ (fallback) │ │
│ └──────┬──────┘ └───────┬────────┘ │
│ │ │ │
└────────────┼─────────────────┼──────────────┘
│ │
┌───────▼───────┐ ┌──────▼──────────┐
│ pp_ocr_ffi.h │ │ paddle_ocr_ │
│ pp_ocr_ffi.cpp│ │ plugin.cpp │
│ (C API) │ │ (MethodChannel) │
└───────┬───────┘ └──────┬──────────┘
│ │
└────────┬────────┘
│
┌───────▼───────┐
│ ocr_engine │
│ .cpp/.h │
│ (OCR core) │
└───────┬───────┘
│
┌──────────┴──────────┐
│ONNX Runtime+ OpenCV │
│(bundled) │
└─────────────────────┘
License #
This project is licensed under the MIT License.
This project uses the following third-party components:
- OpenCV (Apache License 2.0)
- PaddleOCR PP-OCRv6 models (Apache License 2.0)
- ONNX Runtime (MIT License)
See NOTICE for details.