doc_scan_page.dart 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import 'dart:io';
  2. import 'package:flutter/material.dart';
  3. import 'package:fluttertoast/fluttertoast.dart';
  4. import 'package:image_picker/image_picker.dart';
  5. import 'package:image_size_getter/file_input.dart';
  6. import 'package:native_vision/edge_detection.dart';
  7. import 'package:native_vision/native/doc_scanner.dart';
  8. import 'package:native_vision_example/doc_crop_page.dart';
  9. import 'package:native_vision/widget/doc_preview.dart';
  10. import 'package:path_provider/path_provider.dart';
  11. import 'package:image_size_getter/image_size_getter.dart';
  12. import 'loading_overlay.dart';
  13. class DocScanPage extends StatefulWidget {
  14. const DocScanPage({Key? key}) : super(key: key);
  15. @override
  16. State<DocScanPage> createState() => _DocScanPageState();
  17. }
  18. class _DocScanPageState extends State<DocScanPage> {
  19. bool takingPic = false;
  20. GlobalKey<DocPreviewState> globalKey = GlobalKey();
  21. @override
  22. Widget build(BuildContext context) {
  23. final size = MediaQuery.of(context).size;
  24. final displayW = size.width;
  25. final displayH = displayW / 0.75;
  26. return Scaffold(
  27. appBar: AppBar(title: const Text("文档扫描")),
  28. body: SafeArea(
  29. child: Stack(
  30. fit: StackFit.expand,
  31. children: [
  32. DocPreview(key: globalKey, displayW: displayW, displayH: displayH),
  33. Positioned(
  34. left: 50,
  35. right: 50,
  36. bottom: 10,
  37. child: Column(
  38. children: [
  39. SizedBox(
  40. width: 200,
  41. height: 60,
  42. child: TextButton(
  43. onPressed: () async {
  44. if (takingPic) return;
  45. LoadingOverlay.of(context).show();
  46. takingPic = true;
  47. final ret = await globalKey.currentState?.takePic();
  48. if (!mounted) return;
  49. takingPic = false;
  50. if (ret != null) {
  51. Navigator.push(
  52. context,
  53. MaterialPageRoute(
  54. builder: (context) => LoadingOverlay(
  55. child: DocCropPage(
  56. imgPath: ret["ImgPath"],
  57. edgeDetectionResult:
  58. ret["EdgeDetectionResult"]),
  59. )),
  60. );
  61. } else {
  62. Fluttertoast.showToast(
  63. msg: "This is Center Short Toast",
  64. toastLength: Toast.LENGTH_SHORT,
  65. gravity: ToastGravity.CENTER,
  66. timeInSecForIosWeb: 1,
  67. backgroundColor: Colors.red,
  68. textColor: Colors.white,
  69. fontSize: 16.0);
  70. }
  71. LoadingOverlay.of(context).hide();
  72. },
  73. style:
  74. TextButton.styleFrom(backgroundColor: Colors.green),
  75. child: const Text("Take Picture"),
  76. ),
  77. ),
  78. SizedBox(
  79. width: 200,
  80. height: 60,
  81. child: TextButton(
  82. onPressed: () async {
  83. final ImagePicker imagePicker = ImagePicker();
  84. // Pick an image
  85. final XFile? image = await imagePicker.pickImage(
  86. source: ImageSource.gallery);
  87. if (image != null) {
  88. final size = ImageSizeGetter.getSize(
  89. FileInput(File(image.path)));
  90. final tmpDir = (await getTemporaryDirectory()).path;
  91. final outPath =
  92. "$tmpDir/roi_${DateTime.now().millisecondsSinceEpoch}.jpg";
  93. DocScanner docScanner = DocScanner();
  94. await docScanner.init(0.85);
  95. var h = size.height;
  96. var w = size.width;
  97. if (size.needRotate) {
  98. h = size.width;
  99. w = size.height;
  100. }
  101. final result = await docScanner.singleScan(image.path,
  102. outPath, ROI.create(0, 0, w, h, 0, 0));
  103. await docScanner.release();
  104. if (result != null) {
  105. if (!mounted) return;
  106. Navigator.push(
  107. context,
  108. MaterialPageRoute(
  109. builder: (context) => LoadingOverlay(
  110. child: DocCropPage(
  111. imgPath: outPath,
  112. edgeDetectionResult: result),
  113. )),
  114. );
  115. } else {
  116. Fluttertoast.showToast(
  117. msg: "未识别到文档",
  118. toastLength: Toast.LENGTH_SHORT,
  119. gravity: ToastGravity.CENTER,
  120. timeInSecForIosWeb: 1,
  121. backgroundColor: Colors.red,
  122. textColor: Colors.white,
  123. fontSize: 16.0);
  124. }
  125. }
  126. },
  127. // style:
  128. // TextButton.styleFrom(backgroundColor: Colors.green),
  129. child: const Text("Select Photo"),
  130. ),
  131. )
  132. ],
  133. ),
  134. )
  135. ],
  136. ),
  137. ),
  138. );
  139. }
  140. }