main
parent
bfae90faca
commit
73a518733d
30
.metadata
30
.metadata
|
@ -4,7 +4,7 @@
|
|||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "ead455963c12b453cdb2358cad34969c76daf180"
|
||||
revision: "78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
|
@ -13,26 +13,26 @@ project_type: app
|
|||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
base_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
- platform: android
|
||||
create_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
base_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
- platform: ios
|
||||
create_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
base_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
- platform: linux
|
||||
create_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
base_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
- platform: macos
|
||||
create_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
base_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
- platform: web
|
||||
create_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
base_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
- platform: windows
|
||||
create_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
base_revision: ead455963c12b453cdb2358cad34969c76daf180
|
||||
create_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
base_revision: 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9
|
||||
|
||||
# User provided section
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
|
||||
|
||||
{
|
||||
"name": "optictext",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"name": "optictext (profile mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "profile"
|
||||
},
|
||||
{
|
||||
"name": "optictext (release mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "release"
|
||||
},
|
||||
{
|
||||
"name": "Flutter Web (Chrome)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"program": "lib/main.dart",
|
||||
"args": [
|
||||
"--web-port", "8080"
|
||||
],
|
||||
"flutterMode": "debug",
|
||||
"disableWebSecurity": true,
|
||||
"webRenderer": "auto",
|
||||
"deviceName": "Chrome",
|
||||
"args2": []
|
||||
}
|
||||
]
|
||||
}
|
|
@ -5,8 +5,9 @@ import 'package:http_parser/http_parser.dart';
|
|||
|
||||
class HttpUtils {
|
||||
var client = http.Client();
|
||||
Future<String> performHttpRequest(
|
||||
Uint8List imageBytes, String imageName) async {
|
||||
Future<String> checkLang(Uint8List imageBytes, String imageName) async {
|
||||
var client = http.Client();
|
||||
|
||||
var postUri = Uri.parse("http://130.61.88.150/upload");
|
||||
http.MultipartRequest request = http.MultipartRequest("POST", postUri);
|
||||
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
import 'dart:io';
|
||||
import 'package:cpd_app/http_utils.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cpd_app/image_uploader.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'language_utils.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
class ImageTranslation extends StatefulWidget {
|
||||
const ImageTranslation({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ImageTranslation> createState() => _ImageTranslationState();
|
||||
}
|
||||
|
||||
class _ImageTranslationState extends State<ImageTranslation> {
|
||||
XFile? _selectedImage;
|
||||
String _sourceLanguage = 'Auto';
|
||||
String _targetLanguage = 'English';
|
||||
String _translatedText = '';
|
||||
final ImageUploader _imageUploader = ImageUploader();
|
||||
final HttpUtils _httpUtils = HttpUtils();
|
||||
/*1. Text extracten
|
||||
2. Text übersetzen
|
||||
3. Text aus dem alten bild mit farbe überdecken (koordinaten etwas weiter links oben + rechts unten als die erkannten koordinaten)
|
||||
4. Übersetzen Text in neues bild einfügen
|
||||
*/
|
||||
Future<void> uploadImage(
|
||||
Uint8List imageBytes,
|
||||
String sourceLang,
|
||||
String targetLang,
|
||||
) async {
|
||||
setState(() {
|
||||
_translatedText = '';
|
||||
});
|
||||
|
||||
//preprocessing
|
||||
String text = '';
|
||||
if (LanguageUtils.tessLanguages[sourceLang] == 'auto') {
|
||||
String lang = await _httpUtils.checkLang(imageBytes, 'image.jpg');
|
||||
text = await _imageUploader.performOcr(imageBytes, 'image.jpg', lang);
|
||||
sourceLang = LanguageUtils.tessLanguages[sourceLang]!;
|
||||
} else {
|
||||
String langCode = LanguageUtils.tessLanguages[sourceLang]!;
|
||||
text = await _imageUploader.performOcr(imageBytes, 'image.jpg', langCode);
|
||||
}
|
||||
if (text != '') {
|
||||
Map<String, String> requestBody = {
|
||||
'source_language': sourceLang,
|
||||
'target_language': LanguageUtils.translatorLanguages[targetLang]!,
|
||||
'text': text,
|
||||
};
|
||||
|
||||
Map<String, String> headers = {
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
'X-RapidAPI-Key': 'd0fa3c2f3cmsh1805e7a2fed7cc2p1683ebjsna722e2bffafe',
|
||||
'X-RapidAPI-Host': 'text-translator2.p.rapidapi.com',
|
||||
};
|
||||
|
||||
final response = await http.post(
|
||||
Uri.parse('https://text-translator2.p.rapidapi.com/translate'),
|
||||
headers: headers,
|
||||
body: requestBody,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
_translatedText = response.body;
|
||||
setState(() {
|
||||
_translatedText = text;
|
||||
_selectedImage = null;
|
||||
});
|
||||
} else {
|
||||
print('Error: ${response.statusCode}');
|
||||
}
|
||||
print(_translatedText);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> sourceLanguages = LanguageUtils.tessLanguages.keys.toList();
|
||||
List<String> targetLanguages =
|
||||
LanguageUtils.translatorLanguages.keys.toList();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Image Translation'),
|
||||
),
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
// From - Subtle blue background
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.shade100,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
const Text('From', style: TextStyle(color: Colors.blue)),
|
||||
DropdownButton<String>(
|
||||
value: _sourceLanguage,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
_sourceLanguage = newValue!;
|
||||
});
|
||||
},
|
||||
items: sourceLanguages
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Target - Subtle red background
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red.shade100,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
const Text('Target', style: TextStyle(color: Colors.red)),
|
||||
DropdownButton<String>(
|
||||
value: _targetLanguage,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
_targetLanguage = newValue!;
|
||||
});
|
||||
},
|
||||
items: targetLanguages
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
final ImagePicker picker = ImagePicker();
|
||||
final XFile? image =
|
||||
await picker.pickImage(source: ImageSource.gallery);
|
||||
if (image != null) {
|
||||
setState(() {
|
||||
_selectedImage = image;
|
||||
});
|
||||
}
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.all<Color>(Colors.blue),
|
||||
),
|
||||
child: const Text(
|
||||
'Upload Image',
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: _selectedImage != null
|
||||
? () async {
|
||||
if (_selectedImage != null) {
|
||||
File imageFile = File(_selectedImage!.path);
|
||||
List<int> imageBytes = imageFile.readAsBytesSync();
|
||||
await uploadImage(Uint8List.fromList(imageBytes),
|
||||
_sourceLanguage, _targetLanguage);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
child: const Text('Extract Text'),
|
||||
),
|
||||
_translatedText.isNotEmpty
|
||||
? Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: TextFormField(
|
||||
readOnly: true,
|
||||
initialValue: _translatedText,
|
||||
maxLines: null,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Extracted Text',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Clipboard.setData(ClipboardData(text: _translatedText));
|
||||
},
|
||||
child: const Text('Copy to Clipboard'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,8 +4,6 @@ import 'package:flutter_tesseract_ocr/flutter_tesseract_ocr.dart';
|
|||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class ImageUploader {
|
||||
//final http.Client client;
|
||||
|
||||
ImageUploader();
|
||||
|
||||
Future<Uint8List> buildImageFile(String img) async {
|
||||
|
@ -30,4 +28,21 @@ class ImageUploader {
|
|||
|
||||
return text;
|
||||
}
|
||||
|
||||
Future<String> performAdvancedOCR(
|
||||
Uint8List imageBytes, String imageName, String lang) async {
|
||||
Directory tempDir = await getTemporaryDirectory();
|
||||
String tempPath = tempDir.path;
|
||||
File tempImageFile = File('$tempPath/$imageName');
|
||||
await tempImageFile.writeAsBytes(imageBytes);
|
||||
|
||||
String text = await FlutterTesseractOcr.extractHocr(tempImageFile.path,
|
||||
language: lang,
|
||||
args: {
|
||||
"psm": "4",
|
||||
"preserve_interword_spaces": "1",
|
||||
});
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
class LanguageUtils {
|
||||
static Map<String, String> tessLanguages = {
|
||||
'Auto': 'auto',
|
||||
'English': 'eng',
|
||||
'German': 'deu',
|
||||
'French': 'fra',
|
||||
'Spanish': 'spa',
|
||||
'Italian': 'ita',
|
||||
'Portuguese': 'por',
|
||||
'Dutch': 'dut',
|
||||
'Polish': 'pol',
|
||||
'Russian': 'rus',
|
||||
'Japanese': 'jpn',
|
||||
'Chinese (Simplified)': 'chi_sim',
|
||||
'Chinese (Traditional)': 'chi_tra',
|
||||
'Korean': 'kor',
|
||||
'Arabic': 'ara',
|
||||
'Hindi': 'hin',
|
||||
'Indonesian': 'ind',
|
||||
'Malay': 'mal',
|
||||
'Thai': 'tha',
|
||||
'Vietnamese': 'vie',
|
||||
'Turkish': 'tur',
|
||||
'Ukrainian': 'ukr',
|
||||
'Hungarian': 'hun',
|
||||
'Czech': 'cze',
|
||||
'Finnish': 'fin',
|
||||
'Danish': 'dan',
|
||||
'Norwegian': 'nor',
|
||||
'Swedish': 'swe',
|
||||
'Greek': 'gre',
|
||||
'Slovak': 'slo',
|
||||
'Croatian': 'hrv',
|
||||
'Lithuanian': 'lit',
|
||||
'Romanian': 'rum',
|
||||
'Bulgarian': 'bul',
|
||||
'Latvian': 'lav',
|
||||
'Estonian': 'est',
|
||||
'Persian': 'per',
|
||||
'Hebrew': 'heb',
|
||||
'Serbian': 'srp',
|
||||
'Albanian': 'alb',
|
||||
'Tagalog': 'tgl',
|
||||
'Azerbaijani': 'aze',
|
||||
'Basque': 'baq',
|
||||
'Belarusian': 'bel',
|
||||
'Bengali': 'ben',
|
||||
'Bosnian': 'bos',
|
||||
'Cebuano': 'ceb',
|
||||
'Esperanto': 'epo',
|
||||
'Galician': 'glg',
|
||||
'Georgian': 'geo',
|
||||
'Gujarati': 'guj',
|
||||
};
|
||||
|
||||
static Map<String, String> translatorLanguages = {
|
||||
'Auto': 'auto',
|
||||
'English': 'en',
|
||||
'German': 'de',
|
||||
'French': 'fr',
|
||||
'Spanish': 'spa',
|
||||
'Italian': 'ita',
|
||||
'Portuguese': 'por',
|
||||
'Dutch': 'dut',
|
||||
'Polish': 'pol',
|
||||
'Russian': 'rus',
|
||||
'Japanese': 'jpn',
|
||||
'Chinese (Simplified)': 'chi_sim',
|
||||
'Chinese (Traditional)': 'chi_tra',
|
||||
'Korean': 'kor',
|
||||
'Arabic': 'ara',
|
||||
'Hindi': 'hin',
|
||||
'Indonesian': 'ind',
|
||||
'Malay': 'mal',
|
||||
'Thai': 'tha',
|
||||
'Vietnamese': 'vie',
|
||||
'Turkish': 'tur',
|
||||
'Ukrainian': 'ukr',
|
||||
'Hungarian': 'hun',
|
||||
'Czech': 'cze',
|
||||
'Finnish': 'fin',
|
||||
'Danish': 'dan',
|
||||
'Norwegian': 'nor',
|
||||
'Swedish': 'swe',
|
||||
'Greek': 'gre',
|
||||
'Slovak': 'slo',
|
||||
'Croatian': 'hrv',
|
||||
'Lithuanian': 'lit',
|
||||
'Romanian': 'rum',
|
||||
'Bulgarian': 'bul',
|
||||
'Latvian': 'lav',
|
||||
'Estonian': 'est',
|
||||
'Persian': 'per',
|
||||
'Hebrew': 'heb',
|
||||
'Serbian': 'srp',
|
||||
'Albanian': 'alb',
|
||||
'Tagalog': 'tgl',
|
||||
'Azerbaijani': 'aze',
|
||||
'Basque': 'baq',
|
||||
'Belarusian': 'bel',
|
||||
'Bengali': 'ben',
|
||||
'Bosnian': 'bos',
|
||||
'Cebuano': 'ceb',
|
||||
'Esperanto': 'epo',
|
||||
'Galician': 'glg',
|
||||
'Georgian': 'geo',
|
||||
'Gujarati': 'guj',
|
||||
};
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cpd_app/image_translator.dart';
|
||||
import 'package:cpd_app/ocr_page.dart';
|
||||
import 'package:cpd_app/bottom_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -66,7 +67,13 @@ class ImageToolsPage extends StatelessWidget {
|
|||
child: const Text('OCR'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const ImageTranslation()),
|
||||
);
|
||||
},
|
||||
child: const Text('Image Translation'),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import 'dart:io';
|
||||
import 'package:cpd_app/http_utils.dart';
|
||||
import 'package:cpd_app/image_uploader.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'language_utils.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
class OCRPage extends StatefulWidget {
|
||||
const OCRPage({super.key});
|
||||
const OCRPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<OCRPage> createState() => _OCRPageState();
|
||||
|
@ -14,25 +17,31 @@ class _OCRPageState extends State<OCRPage> {
|
|||
String _extractedText = '';
|
||||
final ImageUploader _imageUploader = ImageUploader();
|
||||
final HttpUtils _httpUtils = HttpUtils();
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
uploadImage("lorem.png");
|
||||
}
|
||||
String _selectedLanguage = 'Auto';
|
||||
XFile? _selectedImage;
|
||||
|
||||
Future<void> uploadImage(String img) async {
|
||||
//hier wird der user sein bild auswählen können
|
||||
//aktuell hardcoded bild zum testen
|
||||
String imageName = img;
|
||||
Uint8List imageBytes = await _imageUploader.buildImageFile(imageName);
|
||||
String lang = await _httpUtils.performHttpRequest(imageBytes, imageName);
|
||||
String text = await _imageUploader.performOcr(imageBytes, imageName, lang);
|
||||
Future<void> uploadImage(
|
||||
Uint8List imageBytes, String selectedLanguage) async {
|
||||
setState(() {
|
||||
_extractedText = '';
|
||||
});
|
||||
|
||||
//preprocessing, maybe
|
||||
String text = '';
|
||||
if (selectedLanguage == 'Auto') {
|
||||
String lang = await _httpUtils.checkLang(imageBytes, 'image.jpg');
|
||||
text = await _imageUploader.performOcr(imageBytes, 'image.jpg', lang);
|
||||
} else {
|
||||
String langCode = LanguageUtils.tessLanguages[selectedLanguage]!;
|
||||
text = await _imageUploader.performOcr(imageBytes, 'image.jpg', langCode);
|
||||
}
|
||||
setState(() {
|
||||
_extractedText = text;
|
||||
_selectedImage = null;
|
||||
});
|
||||
}
|
||||
|
||||
List<String> languages = LanguageUtils.tessLanguages.keys.toList();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
@ -43,11 +52,69 @@ class _OCRPageState extends State<OCRPage> {
|
|||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
ElevatedButton(
|
||||
onPressed: () => uploadImage("lorem.png"),
|
||||
child: const Text('Test Upload Image'),
|
||||
DropdownButton<String>(
|
||||
value: _selectedLanguage,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
_selectedLanguage = newValue!;
|
||||
});
|
||||
},
|
||||
items: languages.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
Text(_extractedText),
|
||||
_selectedImage != null
|
||||
? SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
height: MediaQuery.of(context).size.height * 0.4,
|
||||
child: Image.file(File(_selectedImage!.path)),
|
||||
)
|
||||
: Container(),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
final ImagePicker picker = ImagePicker();
|
||||
final XFile? image =
|
||||
await picker.pickImage(source: ImageSource.gallery);
|
||||
if (image != null) {
|
||||
setState(() {
|
||||
_selectedImage = image;
|
||||
});
|
||||
}
|
||||
},
|
||||
child: const Text('Select Image'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: _selectedImage != null
|
||||
? () async {
|
||||
if (_selectedImage != null) {
|
||||
File imageFile = File(_selectedImage!.path);
|
||||
List<int> imageBytes = imageFile.readAsBytesSync();
|
||||
await uploadImage(
|
||||
Uint8List.fromList(imageBytes), _selectedLanguage);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
child: const Text('Extract Text'),
|
||||
),
|
||||
_extractedText.isNotEmpty
|
||||
? Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: TextFormField(
|
||||
readOnly: true,
|
||||
initialValue: _extractedText,
|
||||
maxLines: null,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Extracted Text',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Clipboard.setData(ClipboardData(text: _extractedText));
|
||||
|
|
26
pubspec.lock
26
pubspec.lock
|
@ -93,10 +93,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.2"
|
||||
version: "1.18.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -388,10 +388,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
version: "1.10.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -521,18 +521,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.0"
|
||||
version: "1.11.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
|
||||
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.2"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -553,10 +553,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
|
||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.0"
|
||||
version: "0.6.1"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -585,10 +585,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
|
||||
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.4-beta"
|
||||
version: "0.3.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -614,5 +614,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.1.3 <4.0.0"
|
||||
dart: ">=3.2.0-194.0.dev <4.0.0"
|
||||
flutter: ">=3.7.0"
|
||||
|
|
|
@ -17,6 +17,7 @@ dependencies:
|
|||
http: ^1.1.0
|
||||
flutter_tesseract_ocr:
|
||||
http_parser: ^4.0.2
|
||||
#opencv_4: ^1.0.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in New Issue