1
1
import 'dart:async' ;
2
+ import 'dart:isolate' ;
2
3
import 'dart:typed_data' ;
3
4
4
5
import 'package:flutter/foundation.dart' ;
5
6
import 'package:flutter/material.dart' ;
7
+ import 'package:flutter/services.dart' ;
6
8
7
9
import 'package:image/image.dart' as image;
8
- import 'package:http/http.dart' as http;
9
10
import 'package:loading_indicator/loading_indicator.dart' ;
10
11
11
12
void main () {
@@ -22,15 +23,13 @@ class MyApp extends StatelessWidget {
22
23
theme: ThemeData (
23
24
primarySwatch: Colors .blue,
24
25
),
25
- home: const MyHomePage (title : 'Image Processing Demo' ),
26
+ home: const MyHomePage (),
26
27
);
27
28
}
28
29
}
29
30
30
31
class MyHomePage extends StatefulWidget {
31
- const MyHomePage ({Key ? key, required this .title}) : super (key: key);
32
-
33
- final String title;
32
+ const MyHomePage ({Key ? key}) : super (key: key);
34
33
35
34
@override
36
35
State <MyHomePage > createState () => _MyHomePageState ();
@@ -45,20 +44,36 @@ class _MyHomePageState extends State<MyHomePage> {
45
44
@override
46
45
void initState () {
47
46
super .initState ();
48
- http.get (Uri .parse ('https://picsum.photos/id/428/2529/1581' )).then (
49
- (http.Response response) => setState (() {
50
- _originalImage = response.bodyBytes;
51
- _image = _originalImage;
52
- }),
53
- );
47
+ rootBundle.load ('assets/tulips.jpg' ).then ((ByteData data) {
48
+ setState (() {
49
+ _originalImage = data.buffer.asUint8List ();
50
+ _image = _originalImage;
51
+ });
52
+ });
53
+ }
54
+
55
+ static Uint8List _applySepiaFilter (Uint8List original) {
56
+ final image.Image decoded = image.decodeImage (original.toList ())! ;
57
+ final image.Image sepia = image.sepia (decoded);
58
+ final Uint8List encoded = Uint8List .fromList (image.encodeJpg (sepia));
59
+ return encoded;
54
60
}
55
61
56
62
void _applySepiaFilterSync () {
57
63
setState (() {
58
64
_loading = true ;
59
65
});
60
- // Hack to render the loading indicator before the actual computation
61
- // blocks the main thread.
66
+ final Uint8List filtered = _applySepiaFilter (_image! );
67
+ setState (() {
68
+ _image = filtered;
69
+ _loading = false ;
70
+ });
71
+ }
72
+
73
+ void _applySepiaFilterAsync () {
74
+ setState (() {
75
+ _loading = true ;
76
+ });
62
77
Future .delayed (const Duration (milliseconds: 500 ), () {
63
78
final Uint8List filtered = _applySepiaFilter (_image! );
64
79
setState (() {
@@ -68,19 +83,13 @@ class _MyHomePageState extends State<MyHomePage> {
68
83
});
69
84
}
70
85
71
- static Uint8List _applySepiaFilter (Uint8List original) {
72
- final image.Image decoded = image.decodeImage (original.toList ())! ;
73
- final image.Image sepia = image.sepia (decoded);
74
- final Uint8List encoded = Uint8List .fromList (image.encodeJpg (sepia));
75
- return encoded;
76
- }
77
-
78
- Future <void > _applySepiaFilterAsync () async {
86
+ Future <void > _applySepiaFilterInIsolate () async {
79
87
setState (() {
80
88
_loading = true ;
81
89
});
82
- final Uint8List encoded =
83
- await compute <Uint8List , Uint8List >(_applySepiaFilter, _image! );
90
+ final Uint8List encoded = await compute (_applySepiaFilter, _image! );
91
+ // Alternative with Isolate.run (currently crashes).
92
+ // final Uint8List encoded = await Isolate.run(() => _applySepiaFilter(_image!));
84
93
setState (() {
85
94
_image = encoded;
86
95
_loading = false ;
@@ -97,7 +106,7 @@ class _MyHomePageState extends State<MyHomePage> {
97
106
Widget build (BuildContext context) {
98
107
return Scaffold (
99
108
appBar: AppBar (
100
- title: Text (widget.title ),
109
+ title: const Text ('Image Processing Demo' ),
101
110
),
102
111
body: Stack (
103
112
children: [
@@ -146,6 +155,12 @@ class _MyHomePageState extends State<MyHomePage> {
146
155
: null ,
147
156
child: const Text ('Sepia (async)' ),
148
157
),
158
+ TextButton (
159
+ onPressed: _image == _originalImage && ! _loading
160
+ ? _applySepiaFilterInIsolate
161
+ : null ,
162
+ child: const Text ('Sepia (isolate)' ),
163
+ ),
149
164
TextButton (
150
165
onPressed: _image != _originalImage && ! _loading ? _reset : null ,
151
166
child: const Text ('Reset' ),
0 commit comments