flutter_scalable_ocr_enhanced 1.0.0 copy "flutter_scalable_ocr_enhanced: ^1.0.0" to clipboard
flutter_scalable_ocr_enhanced: ^1.0.0 copied to clipboard

An enhanced wrapper around flutter_scalable_ocr with controller support and detectOnce feature to stop camera after text detection.

example/lib/main.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_scalable_ocr_enhanced/flutter_scalable_ocr_enhanced.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter_native_ocr/flutter_native_ocr.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Enhanced OCR Demo',
      home: EnhancedOCRDemo(),
    );
  }
}

class EnhancedOCRDemo extends StatefulWidget {
  const EnhancedOCRDemo({super.key});

  @override
  State<EnhancedOCRDemo> createState() => _EnhancedOCRDemoState();
}

class _EnhancedOCRDemoState extends State<EnhancedOCRDemo> {
  final EnhancedOCRController _controller = EnhancedOCRController();
  final ImagePicker _picker = ImagePicker();
  final FlutterNativeOcr _nativeOcr = FlutterNativeOcr();
  
  String _currentText = "";
  bool _useCamera = true;
  File? _selectedImage;
  bool _isLoading = false;
  String _recognizedText = "";
  bool _detectOnce = true;

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  // ===============================
  // Pick Image
  // ===============================
  Future<void> _pickImage() async {
    final XFile? image = await _picker.pickImage(source: ImageSource.gallery);

    if (image != null) {
      setState(() {
        _selectedImage = File(image.path);
        _useCamera = false;
        _recognizedText = "";
        _currentText = "";
      });

      _runImageOCR();
    }
  }

  // ===============================
  // OCR From Image
  // ===============================
  Future<void> _runImageOCR() async {
    if (_selectedImage == null) return;

    setState(() {
      _isLoading = true;
    });

    try {
      final text = await _nativeOcr.recognizeText(_selectedImage!.path);

      setState(() {
        _recognizedText = text.isEmpty ? "No text found" : text;
      });
    } catch (e) {
      setState(() {
        _recognizedText = "Error: $e";
      });
    }

    setState(() {
      _isLoading = false;
    });
  }

  // ===============================
  // Switch Back To Camera
  // ===============================
  void _backToCamera() {
    setState(() {
      _useCamera = true;
      _selectedImage = null;
      _recognizedText = "";
      _currentText = "";
    });
    _controller.reset();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Enhanced OCR Demo"),
        backgroundColor: Colors.blue,
        actions: [
          if (_useCamera)
            IconButton(
              icon: const Icon(Icons.photo_library),
              onPressed: _pickImage,
            ),
          if (!_useCamera)
            IconButton(
              icon: const Icon(Icons.camera_alt),
              onPressed: _backToCamera,
            ),
        ],
      ),
      body: Column(
        children: [
          // ===============================
          // CAMERA VIEW
          // ===============================
          if (_useCamera)
            Container(
              height: MediaQuery.of(context).size.height * 0.5,
              child: EnhancedScalableOCR(
                controller: _controller,
                detectOnce: _detectOnce,
                minTextLength: 3,
                boxHeight: MediaQuery.of(context).size.height / 4,
                onTextDetected: (text) {
                  setState(() {
                    _currentText = text;
                  });
                },
                onDetectionComplete: (text) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text("Text captured: $text"),
                      backgroundColor: Colors.green,
                      duration: const Duration(seconds: 2),
                    ),
                  );
                },
                stoppedWidget: Container(
                  color: Colors.green.shade900,
                  child: Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Icon(
                          Icons.check_circle_outline,
                          size: 100,
                          color: Colors.white,
                        ),
                        const SizedBox(height: 20),
                        const Text(
                          "Text Captured Successfully!",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 24,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        const SizedBox(height: 10),
                        if (_controller.detectedText.isNotEmpty)
                          Padding(
                            padding: const EdgeInsets.symmetric(horizontal: 24),
                            child: Text(
                              _controller.detectedText,
                              style: const TextStyle(
                                color: Colors.white70,
                                fontSize: 16,
                              ),
                              textAlign: TextAlign.center,
                              maxLines: 3,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ),
                      ],
                    ),
                  ),
                ),
              ),
            ),

          // ===============================
          // IMAGE VIEW
          // ===============================
          if (!_useCamera && _selectedImage != null)
            Container(
              height: 250,
              margin: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                border: Border.all(color: Colors.grey),
                borderRadius: BorderRadius.circular(8),
              ),
              child: Image.file(
                _selectedImage!,
                fit: BoxFit.contain,
              ),
            ),

          if (_isLoading)
            const Padding(
              padding: EdgeInsets.all(16),
              child: CircularProgressIndicator(),
            ),

          // ===============================
          // CONTROLS
          // ===============================
          if (_useCamera)
            Padding(
              padding: const EdgeInsets.all(16),
              child: Column(
                children: [
                  // Detect Once Toggle
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const Text(
                        "Detect Once Mode:",
                        style: TextStyle(fontSize: 16),
                      ),
                      const SizedBox(width: 10),
                      Switch(
                        value: _detectOnce,
                        onChanged: (value) {
                          setState(() {
                            _detectOnce = value;
                          });
                        },
                      ),
                    ],
                  ),
                  const SizedBox(height: 10),

                  // Control Buttons
                  ListenableBuilder(
                    listenable: _controller,
                    builder: (context, _) {
                      return Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: [
                          ElevatedButton.icon(
                            onPressed: _controller.isActive
                                ? () => _controller.stop()
                                : () => _controller.start(),
                            icon: Icon(
                              _controller.isActive ? Icons.stop : Icons.play_arrow,
                            ),
                            label: Text(
                              _controller.isActive ? "Stop" : "Start",
                            ),
                            style: ElevatedButton.styleFrom(
                              backgroundColor: _controller.isActive
                                  ? Colors.red
                                  : Colors.green,
                              foregroundColor: Colors.white,
                            ),
                          ),
                          if (_controller.isDetectionComplete)
                            ElevatedButton.icon(
                              onPressed: () => _controller.reset(),
                              icon: const Icon(Icons.refresh),
                              label: const Text("Scan Again"),
                              style: ElevatedButton.styleFrom(
                                backgroundColor: Colors.blue,
                                foregroundColor: Colors.white,
                              ),
                            ),
                        ],
                      );
                    },
                  ),
                ],
              ),
            ),

          const SizedBox(height: 10),

          // ===============================
          // TEXT DISPLAY
          // ===============================
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text(
                  "Recognized Text:",
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 16,
                  ),
                ),
                if (_useCamera && _controller.isDetectionComplete)
                  Container(
                    margin: const EdgeInsets.only(left: 8),
                    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                    decoration: BoxDecoration(
                      color: Colors.green.shade100,
                      borderRadius: BorderRadius.circular(12),
                      border: Border.all(color: Colors.green),
                    ),
                    child: const Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.check_circle, size: 14, color: Colors.green),
                        SizedBox(width: 4),
                        Text(
                          "Captured",
                          style: TextStyle(
                            color: Colors.green,
                            fontSize: 12,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ],
                    ),
                  ),
              ],
            ),
          ),

          const SizedBox(height: 8),

          Expanded(
            child: Container(
              width: double.infinity,
              padding: const EdgeInsets.all(16),
              margin: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                border: Border.all(
                  color: _useCamera && _controller.isDetectionComplete
                      ? Colors.green
                      : Colors.grey,
                  width: _useCamera && _controller.isDetectionComplete ? 2 : 1,
                ),
                borderRadius: BorderRadius.circular(8),
                color: _useCamera && _controller.isDetectionComplete
                    ? Colors.green.shade50
                    : Colors.grey.shade50,
              ),
              child: SingleChildScrollView(
                child: Text(
                  _useCamera
                      ? (_currentText.isEmpty ? "Scanning..." : _currentText)
                      : _recognizedText,
                  style: const TextStyle(
                    fontSize: 16,
                    height: 1.5,
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
1
likes
150
points
166
downloads

Publisher

verified publisheriamdk.online

Weekly Downloads

An enhanced wrapper around flutter_scalable_ocr with controller support and detectOnce feature to stop camera after text detection.

Homepage

Documentation

API reference

License

MIT (license)

Dependencies

flutter, flutter_scalable_ocr

More

Packages that depend on flutter_scalable_ocr_enhanced