我正在尝试使用过滤器和图像包进行一些图像处理。我可以使其正常运行,但是它会挂起UI。
class ImageScreen extends StatefulWidget {
static MaterialPageRoute route(String path) => MaterialPageRoute(
builder: (context) => ImageScreen(
imagePath: path,
));
final String imagePath;
const ImageScreen({Key key, this.imagePath}) : super(key: key);
@override
_ImageScreenState createState() => _ImageScreenState();
}
class _ImageScreenState extends State<ImageScreen> {
int value = 0;
Filter _filter;
final _random = Random();
_ImageScreenState();
Widget _animatedWidget = const Center(child: CircularProgressIndicator());
Future<Widget> _createImage(Filter filter) async {
value++;
_filter = filter;
var bytes = await File(widget.imagePath).readAsBytes();
var i = await image.decodeImage( bytes );
_filter.apply(i.getBytes(), i.width, i.height);
return Image(key: ValueKey<int>(_random.nextInt(200)) , image: MemoryImage(image.encodeJpg(i)));
}
void _initiate(Filter filter) {
debugPrint("initializing");
_createImage(filter).then(
(widget)=> setState(()=> _animatedWidget =widget));
debugPrint("done");
}
@override
void initState() {
super.initState();
_initiate(NoFilter());
}
@override
Widget build(BuildContext context) {
return Scaffold(body:
Stack(
children: [
AnimatedSwitcher(child: _animatedWidget, duration: Duration(milliseconds: 200),),
Align(
alignment: Alignment.bottomCenter,
child: Container(
padding: EdgeInsets.only(top: 10, bottom: 10),
color: Color.fromRGBO(200, 200, 200, 0.9),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
FlatButton(
child: Text('Original'),
onPressed: () async {
_initiate(NoFilter());
},
),
FlatButton(
child: Text('B&W'),
onPressed: () {
_initiate(MoonFilter());
},
),
FlatButton(
child: Text('Dusty'),
onPressed: () {
_initiate(ReyesFilter());
},
)
],
),
)
)
],
));
}
}
我想发生的事情是将处理从主线程中删除,然后看到一个不错的过渡。不幸的是,某些东西阻塞了主线程。 按钮陷入按下状态,然后在处理完成后,页面闪烁并显示新图像。
答案 0 :(得分:0)
您必须将此功能设置为async
Future<void> _initiate(Filter filter)async {
debugPrint("initializing");
_createImage(filter).then(
(widget)=> setState(()=> _animatedWidget =widget));
debugPrint("done");
}
如果要调用此函数,则可以调用
onPressed: () async {
await _initiate(NoFilter());
},