import 'dart:io'; import 'package:flutter/material.dart'; import 'package:image_size_getter/file_input.dart'; import 'package:image_size_getter/image_size_getter.dart'; import 'package:native_vision/edge_detection.dart'; import 'package:native_vision/widget/edge_detection_shape.dart'; import 'dart:ui' as ui; import 'package:native_vision/native/doc_cropper.dart'; import 'package:native_vision_example/doc_clean_page.dart'; import 'loading_overlay.dart'; class DocCropPage extends StatefulWidget { final String imgPath; final EdgeDetectionResult edgeDetectionResult; const DocCropPage( {Key? key, required this.imgPath, required this.edgeDetectionResult}) : super(key: key); @override State createState() { return DocCropPageState(); } } class DocCropPageState extends State { GlobalKey imageWidgetKey = GlobalKey(); Future> calculateImgSize() async { final screenSize = MediaQuery.of(context).size; final imgSize = ImageSizeGetter.getSize(FileInput(File(widget.imgPath))); final double width, height; if (imgSize.needRotate) { width = imgSize.height.toDouble(); height = imgSize.width.toDouble(); } else { width = imgSize.width.toDouble(); height = imgSize.height.toDouble(); } final aspectRatio = width / height; final imgW = screenSize.width; final imgH = imgW / aspectRatio; return { "renderedImageSize": ui.Size(imgW, imgH), "originalImageSize": ui.Size(width, height) }; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("裁剪")), body: Stack(children: [ FutureBuilder>( future: calculateImgSize(), builder: (context, snapshot) { final data = snapshot.data; if (data != null) { final renderedImageSize = data["renderedImageSize"]; final originalImageSize = data["originalImageSize"]; return Container( alignment: Alignment.center, color: Colors.blue, child: Stack( children: [ Image.file( File(widget.imgPath), key: imageWidgetKey, width: renderedImageSize!.width, height: renderedImageSize.height, cacheHeight: (renderedImageSize.height * MediaQuery.of(context).devicePixelRatio) .toInt(), cacheWidth: (renderedImageSize.width * MediaQuery.of(context).devicePixelRatio) .toInt(), ), SizedBox( width: renderedImageSize.width, height: renderedImageSize.height, child: EdgeDetectionShape( renderedImageSize: renderedImageSize, originalImageSize: originalImageSize!, edgeDetectionResult: widget.edgeDetectionResult), ) ], ), ); } return Container(); }), Positioned( bottom: 20, left: 0, right: 0, child: Center( child: FloatingActionButton( child: const Icon(Icons.check), onPressed: () async { LoadingOverlay.of(context).show(); final croppedImgPath = await DocCropper.crop( widget.imgPath, widget.edgeDetectionResult); if (mounted && croppedImgPath != null) { debugPrint("croppedImgPath=$croppedImgPath"); LoadingOverlay.of(context).hide(); Navigator.push( context, MaterialPageRoute( builder: (context) => LoadingOverlay( child: DocCleanPage(imgPath: croppedImgPath)), )); } }, ), ), ) ]), ); } }