Init
This commit is contained in:
176
lib/main.dart
Normal file
176
lib/main.dart
Normal file
@@ -0,0 +1,176 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_ffmpeg/stream_information.dart';
|
||||
import 'package:flutter_opencv_example/native_opencv.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';
|
||||
|
||||
const title = 'Native OpenCV Example';
|
||||
|
||||
late Directory tempDir;
|
||||
|
||||
String get dataPath => '${tempDir.path}/data.csv';
|
||||
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
getTemporaryDirectory().then((dir) => tempDir = dir);
|
||||
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: title,
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
home: MyHomePage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
@override
|
||||
_MyHomePageState createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
bool _isProcessed = false;
|
||||
bool _isWorking = false;
|
||||
|
||||
void showVersion() {
|
||||
final scaffoldMessenger = ScaffoldMessenger.of(context);
|
||||
final snackbar = SnackBar(
|
||||
content: Text('OpenCV version: ${opencvVersion()}'),
|
||||
);
|
||||
|
||||
scaffoldMessenger
|
||||
..removeCurrentSnackBar(reason: SnackBarClosedReason.dismiss)
|
||||
..showSnackBar(snackbar);
|
||||
}
|
||||
|
||||
Future<String?> pickAnImage() async {
|
||||
if (Platform.isIOS || Platform.isAndroid) {
|
||||
return FilePicker.platform
|
||||
.pickFiles(
|
||||
dialogTitle: 'Pick an image',
|
||||
type: FileType.video,
|
||||
allowMultiple: false,
|
||||
)
|
||||
.then((v) => v?.files.first.path);
|
||||
} else {
|
||||
return FilePicker.platform
|
||||
.pickFiles(
|
||||
dialogTitle: 'Pick an image',
|
||||
type: FileType.image,
|
||||
allowMultiple: false,
|
||||
)
|
||||
.then((v) => v?.files.first.path);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> takeImageAndProcess() async {
|
||||
final imagePath = await pickAnImage();
|
||||
final FlutterFFprobe _flutterFFmpeg = FlutterFFprobe();
|
||||
|
||||
if (imagePath == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
double? frameRate;
|
||||
var vinfo = await _flutterFFmpeg.getMediaInformation(imagePath);
|
||||
List<StreamInformation>? streams = vinfo.getStreams();
|
||||
if (streams!.length > 0) {
|
||||
for (var stream in streams) {
|
||||
if (stream.getAllProperties()['codec_type'] == "video") {
|
||||
frameRate = int.parse(
|
||||
stream.getAllProperties()['avg_frame_rate'].split("/")[0]) /
|
||||
int.parse(
|
||||
stream.getAllProperties()['avg_frame_rate'].split("/")[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(() {
|
||||
_isWorking = true;
|
||||
});
|
||||
|
||||
// Creating a port for communication with isolate and arguments for entry point
|
||||
final port = ReceivePort();
|
||||
final args = ProcessImageArguments(imagePath, dataPath, frameRate ?? 0.0);
|
||||
|
||||
// Spawning an isolate
|
||||
Isolate.spawn<ProcessImageArguments>(
|
||||
processImage,
|
||||
args,
|
||||
onError: port.sendPort,
|
||||
onExit: port.sendPort,
|
||||
);
|
||||
|
||||
// Making a variable to store a subscription in
|
||||
late StreamSubscription sub;
|
||||
|
||||
// Listening for messages on port
|
||||
sub = port.listen((_) async {
|
||||
// Cancel a subscription after message received called
|
||||
await sub.cancel();
|
||||
|
||||
setState(() {
|
||||
_isProcessed = true;
|
||||
_isWorking = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(title)),
|
||||
body: Stack(
|
||||
children: <Widget>[
|
||||
Center(
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: <Widget>[
|
||||
if (_isProcessed && !_isWorking)
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 3000, maxHeight: 300),
|
||||
// child: Image.file(
|
||||
// File(tempPath),
|
||||
// alignment: Alignment.center,
|
||||
// ),
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
child: Text('Show version'),
|
||||
onPressed: showVersion,
|
||||
),
|
||||
ElevatedButton(
|
||||
child: Text('Process photo'),
|
||||
onPressed: takeImageAndProcess,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
if (_isWorking)
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
color: Colors.black.withOpacity(.7),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user