summaryrefslogtreecommitdiff
path: root/lib/main.dart
diff options
context:
space:
mode:
authorxAlpharax <42233094+xAlpharax@users.noreply.github.com>2023-09-20 03:48:13 +0300
committerxAlpharax <42233094+xAlpharax@users.noreply.github.com>2023-09-20 03:48:13 +0300
commitaf6e4b99a757c58404b5b4b3adc94ffeb784199d (patch)
tree6e3fe795ee67207f8be284a7a1bbc50cd82a2df1 /lib/main.dart
parent75774f00f240d228a3958fa002fde29c9a94f877 (diff)
Initial full migration of the project.
Changes to be committed: new file: .gitignore new file: .metadata new file: README.md new file: analysis_options.yaml new file: android/.gitignore new file: android/app/build.gradle new file: android/app/src/debug/AndroidManifest.xml new file: android/app/src/main/AndroidManifest.xml new file: android/app/src/main/kotlin/com/example/ocr/MainActivity.kt new file: android/app/src/main/res/drawable-hdpi/ic_launcher_background.png new file: android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png new file: android/app/src/main/res/drawable-mdpi/ic_launcher_background.png new file: android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png new file: android/app/src/main/res/drawable-v21/launch_background.xml new file: android/app/src/main/res/drawable-xhdpi/ic_launcher_background.png new file: android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png new file: android/app/src/main/res/drawable-xxhdpi/ic_launcher_background.png new file: android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png new file: android/app/src/main/res/drawable-xxxhdpi/ic_launcher_background.png new file: android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png new file: android/app/src/main/res/drawable/launch_background.xml new file: android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file: android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file: android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file: android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file: android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file: android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file: android/app/src/main/res/values-night/styles.xml new file: android/app/src/main/res/values/colors.xml new file: android/app/src/main/res/values/styles.xml new file: android/app/src/profile/AndroidManifest.xml new file: android/build.gradle new file: android/gradle.properties new file: android/gradle/wrapper/gradle-wrapper.properties new file: android/settings.gradle new file: assets/MegaViewLogo.png new file: ios/.gitignore new file: ios/Flutter/AppFrameworkInfo.plist new file: ios/Flutter/Debug.xcconfig new file: ios/Flutter/Release.xcconfig new file: ios/Podfile new file: ios/Podfile.lock new file: ios/Runner.xcodeproj/project.pbxproj new file: ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file: ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file: ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file: ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file: ios/Runner.xcworkspace/contents.xcworkspacedata new file: ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file: ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file: ios/Runner/AppDelegate.swift new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file: ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file: ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file: ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file: ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file: ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file: ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file: ios/Runner/Base.lproj/LaunchScreen.storyboard new file: ios/Runner/Base.lproj/Main.storyboard new file: ios/Runner/Info.plist new file: ios/Runner/Runner-Bridging-Header.h new file: ios/RunnerTests/RunnerTests.swift new file: lib/main.dart new file: lib/result_screen.dart new file: pubspec.lock new file: pubspec.yaml new file: test/widget_test.dart
Diffstat (limited to 'lib/main.dart')
-rw-r--r--lib/main.dart241
1 files changed, 241 insertions, 0 deletions
diff --git a/lib/main.dart b/lib/main.dart
new file mode 100644
index 0000000..6480384
--- /dev/null
+++ b/lib/main.dart
@@ -0,0 +1,241 @@
+import 'dart:io';
+
+import 'package:camera/camera.dart';
+import 'package:flutter/material.dart';
+import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart';
+import 'package:permission_handler/permission_handler.dart';
+import 'package:flutter_tts/flutter_tts.dart';
+import 'package:ocr/result_screen.dart';
+
+void main() {
+ runApp(const App());
+}
+
+class App extends StatelessWidget {
+ const App({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'MegaView Text',
+ theme: ThemeData(
+ colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurpleAccent),
+ useMaterial3: true,
+ ),
+ debugShowCheckedModeBanner: false,
+ home: const MainScreen(),
+ );
+ }
+}
+
+class MainScreen extends StatefulWidget {
+ const MainScreen({super.key});
+
+ @override
+ State<MainScreen> createState() => _MainScreenState();
+}
+
+class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
+ bool _isPermissionGranted = false;
+
+ late final Future<void> _future;
+ CameraController? _cameraController;
+
+ final textRecognizer = TextRecognizer();
+
+ FlutterTts flutterTts = FlutterTts(); // TTS
+
+ @override
+ void initState() {
+ super.initState();
+ initTTS(); // TTS
+
+ WidgetsBinding.instance.addObserver(this);
+
+ _future = _requestCameraPermission();
+ }
+
+ Future<void> initTTS() async { // TTS
+ await flutterTts.setLanguage("en-US"); // Set the language you want
+ await flutterTts.setSpeechRate(0.5); // Adjust speech rate (1.0 is normal but too fast for my liking)
+ await flutterTts.setVolume(1.0); // Adjust volume (0.0 to 1.0)
+ await flutterTts.setPitch(1.0); // Adjust pitch (1.0 is normal)
+
+ // You can set other configurations as well
+
+ // Check if TTS is available
+ // bool isAvailable = await flutterTts.isLanguageAvailable("en-US");
+ // print("TTS is available: $isAvailable");
+ }
+
+ Future<void> speak(String text) async {
+ await flutterTts.speak(text); // TTS
+ }
+
+ @override
+ void dispose() {
+ WidgetsBinding.instance.removeObserver(this);
+ _stopCamera();
+ textRecognizer.close();
+ flutterTts.stop(); // TTS Stop
+ super.dispose();
+ }
+
+ @override
+ void didChangeAppLifecycleState(AppLifecycleState state) {
+ if (_cameraController == null || !_cameraController!.value.isInitialized) {
+ return;
+ }
+
+ if (state == AppLifecycleState.inactive) {
+ _stopCamera();
+ } else if (state == AppLifecycleState.resumed &&
+ _cameraController != null &&
+ _cameraController!.value.isInitialized) {
+ _startCamera();
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return FutureBuilder(
+ future: _future,
+ builder: (context, snapshot) {
+ return Stack(
+ children: [
+ if (_isPermissionGranted)
+ FutureBuilder<List<CameraDescription>>(
+ future: availableCameras(),
+ builder: (context, snapshot) {
+ if (snapshot.hasData) {
+ _initCameraController(snapshot.data!);
+
+ return Center(child: CameraPreview(_cameraController!));
+ } else {
+ return const LinearProgressIndicator();
+ }
+ },
+ ),
+ Scaffold(
+ appBar: AppBar(
+ backgroundColor: Theme.of(context).colorScheme.inversePrimary,
+ title: const Text('MegaView Text Recognition'),
+ ),
+ backgroundColor: _isPermissionGranted ? Colors.transparent : null,
+ body: _isPermissionGranted
+ ? Column(
+ children: [
+ Expanded(
+ child: Container(),
+ ),
+ Container(
+ padding: const EdgeInsets.only(bottom: 13.0),
+ child: Center(
+ child: ElevatedButton(
+ onPressed: _scanImage,
+ child: const Text('Scan text'),
+ ),
+ ),
+ ),
+ ],
+ )
+ : Center(
+ child: Container(
+ padding: const EdgeInsets.only(left: 24.0, right: 24.0),
+ child: const Text(
+ 'Camera permission denied',
+ textAlign: TextAlign.center,
+ ),
+ ),
+ ),
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ Future<void> _requestCameraPermission() async {
+ final status = await Permission.camera.request();
+ _isPermissionGranted = status == PermissionStatus.granted;
+ }
+
+ void _startCamera() {
+ if (_cameraController != null) {
+ _cameraSelected(_cameraController!.description);
+ }
+ }
+
+ void _stopCamera() {
+ if (_cameraController != null) {
+ _cameraController?.dispose();
+ }
+ }
+
+ void _initCameraController(List<CameraDescription> cameras) {
+ if (_cameraController != null) {
+ return;
+ }
+
+ // Select the first rear camera.
+ CameraDescription? camera;
+ for (var i = 0; i < cameras.length; i++) {
+ final CameraDescription current = cameras[i];
+ if (current.lensDirection == CameraLensDirection.back) {
+ camera = current;
+ break;
+ }
+ }
+
+ if (camera != null) {
+ _cameraSelected(camera);
+ }
+ }
+
+ Future<void> _cameraSelected(CameraDescription camera) async {
+ _cameraController = CameraController(
+ camera,
+ ResolutionPreset.high,
+ enableAudio: false,
+ );
+
+ await _cameraController!.initialize();
+ await _cameraController!.setFlashMode(FlashMode.off);
+
+ if (!mounted) {
+ return;
+ }
+ setState(() {});
+ }
+
+ Future<void> _scanImage() async {
+ if (_cameraController == null) return;
+
+ final navigator = Navigator.of(context);
+
+ try {
+ final pictureFile = await _cameraController!.takePicture();
+
+ final file = File(pictureFile.path);
+
+ final inputImage = InputImage.fromFile(file);
+ final recognizedText = await textRecognizer.processImage(inputImage);
+
+ speak(recognizedText.text);
+
+ await navigator.push(
+ MaterialPageRoute(
+ builder: (BuildContext context) =>
+ ResultScreen(text: recognizedText.text)
+ ),
+ );
+ } catch (e) {
+ // ignore: use_build_context_synchronously
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(
+ content: Text('An error occurred when scanning text'),
+ ),
+ );
+ }
+ }
+} \ No newline at end of file