如何在 Flutter 中使用MemoryImage【Flutter专题】
MemoryImage
,包括如何将图像转换为所需的数据类型。
如何在 Flutter 中使用MemoryImage
,
Flutter 有一些 ImageProvider 的实现,其中之一是 MemoryImage,用于从内存中加载原始图像。由于图像数据已经在内存中,这是最快的 ImageProvider 类型。下面是 Flutter 的 ImgaeProvider 从最快到最慢的列表。
-
MemoryImage
-
AssetImage
-
FileImage
-
NetworkImage
MemoryImage 的构造函数只有一个必填参数:bytes,类型为Unit8List。它包含要解码成image的字节。另一个是可选的,是一个double值的scale,使用scale来表示图像的大小。
MemoryImage(this.bytes, { this.scale = 1.0 })
如果图像来自assets,您可以按照下面的示例进行操作。
Uint8List data = (await rootBundle.load('assets/images/pikachu.png'))
.buffer
.asUint8List();
上面的代码使用AssetBundle
的load
方法来加载assets图像以获取Future<ByteData>
。然后,使用 buffer 属性获取具有 asUint8List 方法的 ByteBuffer,用于获取可以传递给构造函数的适当数据类型。
如果图像来自网络,您可以通过类似的方式将其转换为 Uint8List,但您需要使用 NetworkAssetBundle,它扩展了 AssetBundle。
Uint8List data = (await NetworkAssetBundle(Uri.parse('https://luckly007.oss-cn-beijing.aliyuncs.com'))
.load("/image/image-20211124085239175.png")
)
.buffer
.asUint8List();
有了所需的数据类型后,就很容易构造一个MemoryImage
. 只需将数据作为第一个参数调用构造函数即可。或者,您还可以传递可选参数scale
。
MemoryImage(imageData, scale: 2))
下面是一个简单的应用程序,它使用 MemoryImage
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: MemoryImageApp(),
);
}
}
class MemoryImageApp extends StatefulWidget {
@override
_MemoryImageExampleState createState() {
return _MemoryImageExampleState();
}
}
class _MemoryImageExampleState extends State {
late Uint8List imageData;
@override
void initState() {
super.initState();
loadAsset();
}
void loadAsset() async {
Uint8List data = (await rootBundle.load('assets/images/pikachu.png'))
.buffer
.asUint8List();
setState(() => this.imageData = data);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('坚果前端'),
),
body: Center(child: _ImageWrapper()),
);
}
Widget _ImageWrapper() {
if (imageData == null) {
return CircularProgressIndicator();
}
return Container(
width: 150,
height: 150,
decoration: BoxDecoration(
image: new DecorationImage(
fit: BoxFit.cover, image: MemoryImage(imageData, scale: 0.5)),
),
);
}
}
首先,它将图像从assets转换为 Uint8List,然后将结果存储为状态变量。之后,图像数据用作 MemoryImage 的 bytes 属性。将可选的 scale 属性设置为 0.5 时,图像会按比例缩小。 不仅用于 BoxDecoration,它还可以用于任何具有 ImageProvider 类型属性的小部件,例如 Image 和 CircleImage
使用Image.Memory()
命名构造函数
这是另一种创建 MemoryImage 的方法,它也需要图像的 Uint8List 数据。
下面是命名构造函数的基本用法
image: new DecorationImage(
fit: BoxFit.cover,
image: Image.memory(imageData).image
),
您可以在构造函数中传递大量可用参数,如下所示。唯一需要的参数是bytes
.
-
Uint8List bytes
* : 图像数据。 -
Key key
: 小部件键,用于控制是否应更换。 -
double scale
: 如何缩放图像。默认为 1.0。 -
ImageFrameBuilder frameBuilder
:负责创建代表此图像的小部件的构建器函数。 -
String semanticLabel
:图像的语义描述。 -
bool excludeFromSemantics
: 是否从语义中排除此图像。默认为false
. -
double width
:图像的高度。 -
double height
:图像的高度。 -
Color color
:根据colorBlendMode
值与图像混合的颜色。 -
BlendMode colorBlendMode
:如何将颜色与图像结合起来。 -
BoxFit fit
:如何将图像写入布局期间分配的空间。 -
AlignmentGeometry alignment
:如何在其边界内对齐图像。 -
ImageRepeat repeat
:如何绘制图像未覆盖的布局边界的任何部分。 -
Unit8List bytes
*:图像数据。 -
Rect centerSlice
:九块图像的中心切片。 -
bool matchTextDirection
: 是否使用 的值TextDirection
来绘制图像。默认为false
. -
bool gaplessPlayback
:当图片提供者改变时是否继续显示旧图片。默认为false
. -
FilterQuality filterQuality
:FilterQuality
图片的。默认为FilterQuality.low
. -
int cacheWidth
: 表示必须以指定的宽度对图像进行解码。 -
int cacheHeight
:表示必须在指定高度解码图像。
*: 必需的
无论是使用 MemoryImage 构造函数还是 Image.Memory 命名构造函数,都需要先将图像数据设为 Uint8List。之后,只需将数据传递给构造函数即可显示图像。
- 点赞
- 收藏
- 关注作者
评论(0)