130 lines
4.3 KiB
Dart
130 lines
4.3 KiB
Dart
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({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<OCRPage> createState() => _OCRPageState();
|
|
}
|
|
|
|
class _OCRPageState extends State<OCRPage> {
|
|
String _extractedText = '';
|
|
final ImageUploader _imageUploader = ImageUploader();
|
|
final HttpUtils _httpUtils = HttpUtils();
|
|
String _selectedLanguage = 'Auto';
|
|
XFile? _selectedImage;
|
|
|
|
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(
|
|
appBar: AppBar(
|
|
title: const Text('OCR'),
|
|
),
|
|
body: Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
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(),
|
|
),
|
|
_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));
|
|
},
|
|
child: const Text('Copy to Clipboard'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|