249 lines
8.1 KiB
Plaintext
249 lines
8.1 KiB
Plaintext
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
|
import '../../models/key_value.dart';
|
|
import 'package:image_picker/image_picker.dart';
|
|
import 'package:tesseract_ocr/tesseract_ocr.dart';
|
|
import '../../generated/l10n.dart';
|
|
|
|
class OCRScan extends StatefulWidget {
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => OCRScanState();
|
|
|
|
}
|
|
|
|
class OCRScanState extends State<OCRScan> {
|
|
String _extractText;
|
|
List<KeyValue> docTypes = [];
|
|
KeyValue selectedDocType;
|
|
List<KeyValue> docLan = [];
|
|
KeyValue selectedDocLan;
|
|
bool _reading;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
leading: IconButton(
|
|
icon: Icon(Icons.arrow_back_ios),
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
),
|
|
title: Text(S
|
|
.of(context)
|
|
.ocr_scan),
|
|
backgroundColor: Theme
|
|
.of(context)
|
|
.primaryColor,
|
|
),
|
|
body: ListView.builder(
|
|
itemCount: 4,
|
|
itemBuilder: (BuildContext context, int i) {
|
|
Widget item;
|
|
switch(i) {
|
|
case 0:
|
|
item = Container(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
child: Text(
|
|
S.of(context).document_type,
|
|
),
|
|
),
|
|
Container(
|
|
child: DropdownButton<KeyValue>(
|
|
items: docTypes.map((e) {
|
|
return DropdownMenuItem<KeyValue>(
|
|
value: e,
|
|
child: Text(
|
|
e.name
|
|
),
|
|
);
|
|
}).toList(),
|
|
hint: Text(
|
|
S.of(context).select_document_type,
|
|
),
|
|
onChanged: (newValue) {
|
|
setState(() {
|
|
selectedDocType = newValue;
|
|
});
|
|
},
|
|
isExpanded: true,
|
|
value: selectedDocType,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
break;
|
|
case 1:
|
|
item = Container(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
child: Text(
|
|
S.of(context).document_langage,
|
|
),
|
|
),
|
|
Container(
|
|
child: DropdownButton<KeyValue>(
|
|
items: docLan.map((e) {
|
|
return DropdownMenuItem<KeyValue>(
|
|
value: e,
|
|
child: Text(
|
|
e.name
|
|
),
|
|
);
|
|
}).toList(),
|
|
hint: Text(
|
|
S.of(context).select_document_lanuage,
|
|
),
|
|
onChanged: (newValue) {
|
|
setState(() {
|
|
selectedDocLan = newValue;
|
|
});
|
|
},
|
|
isExpanded: true,
|
|
value: selectedDocLan,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
break;
|
|
case 2:
|
|
item = Container(
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
padding: EdgeInsets.only(right: 10.0),
|
|
child: RaisedButton.icon(
|
|
elevation: 2.0,
|
|
shape: new RoundedRectangleBorder(
|
|
borderRadius: new BorderRadius.circular(5.0),
|
|
),
|
|
color: const Color(0xFFFFB822),
|
|
icon: Icon(Icons.camera_alt_outlined),
|
|
label: Text(
|
|
S.of(context).from_camera,
|
|
),
|
|
onPressed: _reading != null && _reading == true ? null : () {
|
|
getPicFromCamera();
|
|
},
|
|
),
|
|
),
|
|
Container(
|
|
padding: EdgeInsets.only(right: 10.0),
|
|
child: RaisedButton.icon(
|
|
elevation: 2.0,
|
|
shape: new RoundedRectangleBorder(
|
|
borderRadius: new BorderRadius.circular(5.0),
|
|
),
|
|
color: const Color(0xFFEFFE00),
|
|
icon: Icon(Icons.image_search),
|
|
label: Text(
|
|
S.of(context).from_gallery,
|
|
),
|
|
onPressed: _reading != null && _reading == true ? null : () {
|
|
getPicFromGallery();
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
break;
|
|
case 3:
|
|
item = SizedBox.shrink();
|
|
if (_reading != null && _reading) {
|
|
item = _reading == null ? SizedBox.shrink() :
|
|
Container(
|
|
padding: EdgeInsets.only(top: 12.0),
|
|
child: _reading ? SpinKitCircle(
|
|
size: 24.0,
|
|
color: Colors.blue,
|
|
) : Icon(Icons.done),
|
|
);
|
|
} else if (_extractText != null) {
|
|
item = Container(
|
|
child: RaisedButton.icon(
|
|
onPressed: () {
|
|
|
|
},
|
|
color: const Color(0xEE22EE00),
|
|
icon: Icon(Icons.arrow_circle_up),
|
|
label: Text(
|
|
S.of(context).submit_to_generate
|
|
)),
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
return Container(
|
|
padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 8.0, bottom: 8.0),
|
|
child: item,
|
|
);
|
|
}
|
|
),
|
|
);
|
|
}
|
|
|
|
Future getPicFromCamera() async {
|
|
final picker = ImagePicker();
|
|
var image = await picker.getImage(source: ImageSource.camera);
|
|
print(image.path);
|
|
extractText(image.path);
|
|
}
|
|
|
|
Future getPicFromGallery() async {
|
|
final picker = ImagePicker();
|
|
var image = await picker.getImage(source: ImageSource.gallery);
|
|
print(image.path);
|
|
extractText(image.path);
|
|
}
|
|
|
|
Future extractText(String filePath) async {
|
|
int _extractTime = 0;
|
|
setState(() {
|
|
_reading = true;
|
|
_extractText = null;
|
|
});
|
|
var watch = Stopwatch()..start();
|
|
_extractText = await TesseractOcr.extractText(filePath, language: selectedDocLan.value);
|
|
_extractTime = watch.elapsedMilliseconds;
|
|
print(_extractText);
|
|
print('Time: $_extractTime');
|
|
setState(() {
|
|
_reading = false;
|
|
});
|
|
}
|
|
|
|
@override
|
|
void didChangeDependencies() {
|
|
super.didChangeDependencies();
|
|
docTypes.add(KeyValue(S.of(context).ubereats_receipt, 'ubereats-receipt'));
|
|
docTypes.add(KeyValue(S.of(context).business_card, 'business-card'));
|
|
var eng = KeyValue(S.of(context).english, 'eng');
|
|
docLan.add(eng);
|
|
docLan.add(KeyValue(S.of(context).chinese_simplified, 'chi_sim'));
|
|
docLan.add(KeyValue(S.of(context).chinese_traditional, 'chi_tra'));
|
|
if (selectedDocLan == null) {
|
|
setState(() {
|
|
selectedDocLan = eng;
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
}
|
|
} |