Как определить ширину и высоту изображения в Flutter?
Предположим, я объявил свое изображение в моем pubspec.yaml следующим образом:
assets:
- assets/kitten.jpg
И мой код флаттера таков:
void main() {
runApp(
new Center(
child: new Image.asset('assets/kitten.jpg'),
),
);
}
Теперь, когда у меня есть new Image.asset()
, как мне определить ширину и высоту этого изображения? Например, я просто хочу распечатать изображение ширины и высоты.
(Это похоже на dart: ui. Класс Image имеет ширину и высоту, но не уверен, как перейти от виджета Image к dart: ui Image.)
Спасибо!
Ответы
Ответ 1
ОБНОВЛЕННОЕ РЕШЕНИЕ:
С новой версией флаттера старое решение устарело. Теперь addListener
нужен ImageStreamListener
.
Widget build(BuildContext context) {
Image image = new Image.network('https://i.stack.imgur.com/lkd0a.png');
Completer<ui.Image> completer = new Completer<ui.Image>();
image.image
.resolve(new ImageConfiguration())
.addListener(ImageStreamListener(ImageInfo info, bool _) {
completer.complete(info.image));
})
...
...
ОРИГИНАЛЬНАЯ ВЕРСИЯ:
Если у вас уже есть виджет Image
, вы можете прочитать ImageStream
из него, вызвав resolve
на его ImageProvider
.
import 'dart:ui' as ui;
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(new MaterialApp(
home: new MyHomePage(),
));
}
class MyHomePage extends StatelessWidget {
Widget build(BuildContext context) {
Image image = new Image.network('https://i.stack.imgur.com/lkd0a.png');
Completer<ui.Image> completer = new Completer<ui.Image>();
image.image
.resolve(new ImageConfiguration())
.addListener((ImageInfo info, bool _) => completer.complete(info.image));
return new Scaffold(
appBar: new AppBar(
title: new Text("Image Dimensions Example"),
),
body: new ListView(
children: [
new FutureBuilder<ui.Image>(
future: completer.future,
builder: (BuildContext context, AsyncSnapshot<ui.Image> snapshot) {
if (snapshot.hasData) {
return new Text(
'${snapshot.data.width}x${snapshot.data.height}',
style: Theme.of(context).textTheme.display3,
);
} else {
return new Text('Loading...');
}
},
),
image,
],
),
);
}
}
Ответ 2
Вы можете resolve
ImageProvider
для получения ImageStream
, а затем использовать addListener
для уведомления, когда изображение будет готово.
import 'dart:ui' as ui;
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(new MaterialApp(
home: new MyHomePage(),
));
}
class MyHomePage extends StatelessWidget {
Future<ui.Image> _getImage() {
Completer<ui.Image> completer = new Completer<ui.Image>();
new NetworkImage('https://i.stack.imgur.com/lkd0a.png')
.resolve(new ImageConfiguration())
.addListener((ImageInfo info, bool _) => completer.complete(info.image));
return completer.future;
}
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Image Dimensions Example"),
),
body: new Center(
child: new FutureBuilder<ui.Image>(
future: _getImage(),
builder: (BuildContext context, AsyncSnapshot<ui.Image> snapshot) {
if (snapshot.hasData) {
ui.Image image = snapshot.data;
return new Text(
'${image.width}x${image.height}',
style: Theme.of(context).textTheme.display4);
} else {
return new Text('Loading...');
}
},
),
),
);
}
}
Ответ 3
Другие ответы кажутся слишком сложными, если вы просто хотите использовать ширину и высоту изображения в асинхронной функции. Вы можете получить разрешение изображения, используя flutter lib, вот так:
import 'dart:io';
File image = new File('image.png'); // Or any other way to get a File instance.
var decodedImage = await decodeImageFromList(image.readAsBytesSync());
print(decodedImage.width);
print(decodedImage.height);
Ответ 4
С новой версией флаттера старое решение не работает, например:
image.image
.resolve(new ImageConfiguration())
.addListener((ImageInfo info, bool _) => completer.complete(info.image));
Ниже рабочая версия:
_image.image
.resolve(new ImageConfiguration())
.addListener(new ImageStreamListener((ImageInfo image, bool _) {
completer.complete(image.image);
}));
Ответ 5
Создайте метод, например:
Future<Size> _calculateImageDimension() {
Completer<Size> completer = Completer();
Image image = Image.network("https://i.stack.imgur.com/lkd0a.png");
image.image.resolve(ImageConfiguration()).addListener(
ImageStreamListener(
(ImageInfo image, bool synchronousCall) {
var myImage = image.image;
Size size = Size(myImage.width.toDouble(), myImage.height.toDouble());
completer.complete(size);
},
),
);
return completer.future;
}
И используйте это как:
_calculateImageDimension().then((size) => print("size = ${size}")); // 487.0,696.0