写点什么

如何在 Flutter 中使用 MemoryImage【Flutter 专题 23】

作者:坚果前端
  • 2021 年 12 月 18 日
  • 本文字数:2296 字

    阅读完需:约 8 分钟

本教程将向您展示如何在 Flutter 中使用MemoryImage,包括如何将图像转换为所需的数据类型。

如何在 Flutter 中使用MemoryImage

Flutter 有一些 ImageProvider 的实现,其中之一是 MemoryImage,用于从内存中加载原始图像。由于图像数据已经在内存中,这是最快的 ImageProvider 类型。下面是 Flutter 的 ImgaeProvider 从最快到最慢的列表。


  1. MemoryImage

  2. AssetImage

  3. FileImage

  4. NetworkImage


MemoryImage 的构造函数只有一个必填参数:bytes,类型为 Unit8List。它包含要解码成 image 的字节。另一个是可选的,是一个 double 值的 scale,使用 scale 来表示图像的大小。


  MemoryImage(this.bytes, { this.scale = 1.0 })
复制代码


您需要将图像数据设为 Unit8List 字节。要将图像转换为 Unit8List,您可以使用 Flutter 的 AssetBundle。 AssetBundle 的使用取决于图像的来源。


如果图像来自 assets,您可以按照下面的示例进行操作。


  Uint8List data = (await rootBundle.load('assets/images/pikachu.png'))          .buffer          .asUint8List();
复制代码


上面的代码使用AssetBundleload方法来加载 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。之后,只需将数据传递给构造函数即可显示图像。


发布于: 56 分钟前阅读数: 4
用户头像

坚果前端

关注

此间若无火炬,我便是唯一的光 2020.10.25 加入

公众号:“坚果前端”,华为云享专家,51CTO博客首席体验官,专注于大前端技术的分享,包括Flutter,小程序,安卓,VUE,JavaScript。

评论

发布
暂无评论
如何在 Flutter 中使用MemoryImage【Flutter专题23】