Flutter AVIF图像格式支持插件flutter_avif的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter AVIF图像格式支持插件flutter_avif的使用

简介

flutter_avif 是一个用于在Flutter应用程序中查看和编码AVIF图像的插件。它提供了与Flutter内置Image widget相似的API,可以方便地集成到现有项目中。

安装

要将 flutter_avif 添加到你的Flutter应用,请按照 pub.dev上的安装说明 进行操作。

dependencies:
  flutter_avif: ^latest_version # 替换为最新版本号

然后执行 flutter pub get 来安装依赖。

使用方法

显示AVIF图片

AvifImage widget 提供了三种方式来加载和显示AVIF图像:从文件、资源或网络加载。

  • 从文件加载
AvifImage.file(
    file, // File对象
    height: 200,
    fit: BoxFit.contain,
)
  • 从资源加载
AvifImage.asset(
    "assets/test.avif", // 资源路径
    height: 200,
    fit: BoxFit.contain,
)
  • 从网络加载
AvifImage.network(
    "https://example.com/test.avif", // 图片URL
    height: 200,
    fit: BoxFit.contain,
)

此外,对于需要缓存的网络图片,可以使用 CachedNetworkAvifImage

CachedNetworkAvifImage(
    "https://example.com/test.avif",
    height: 200,
    fit: BoxFit.contain,
)

编码(转换)其他格式为AVIF

可以通过 encodeAvif 方法将其他格式(如GIF或PNG)转换为AVIF格式:

import 'package:flutter_avif/flutter_avif.dart';

// 将资产中的GIF转换为AVIF并保存到输出文件
final asset = await rootBundle.load("assets/asset.gif");
final avifBytes = await encodeAvif(asset.buffer.asUint8List());
final outputFile = File('output.avif');
await outputFile.writeAsBytes(avifBytes);

// 或者将本地PNG文件转换为AVIF
final inputFile = File('input.png');
final inputBytes = await inputFile.readAsBytes();
final avifBytes = await encodeAvif(inputBytes);
final outputFile = File('output.avif');
await outputFile.writeAsBytes(avifBytes);

解码AVIF

decodeAvif 函数可用于解码AVIF文件为一系列 dart:ui.Image 对象:

final bytes = await rootBundle.load('assets/multiframe.avif');
final frames = await decodeAvif(bytes.buffer.asUint8List());

// frames是一个包含AvifFrameInfo对象的列表,每个对象代表一帧
for (var frame in frames) {
  print(frame.duration); // 每帧的持续时间
  // 可以使用frame.image绘制每一帧
}

自定义动画控制器

对于多帧AVIF图像,你可以结合 AnimationController 来控制动画播放:

import 'package:flutter_avif/flutter_avif.dart';

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> with SingleTickerProviderStateMixin {
  late AnimationController controller;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(vsync: this);
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AvifAnimation(
      controller: controller,
      image: const AssetAvifImage('assets/multiframe.avif'),
      onLoaded: (duration, fps) {
        controller.forward(); // 开始播放动画
      },
    );
  }
}

示例代码

下面是一个完整的示例,展示了如何在Flutter应用中使用 flutter_avif 插件:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_avif/flutter_avif.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Widget encoderOutput = Container();
  Widget encoderOutput2 = Container();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
          actions: [
            IconButton(
              icon: const Icon(Icons.repeat_outlined),
              tooltip: 'Encode Demo',
              onPressed: () async {
                final bytes = await rootBundle.load("assets/vettel.gif");
                final avifBytes = await encodeAvif(bytes.buffer.asUint8List());
                setState(() {
                  encoderOutput = AvifImage.memory(
                    avifBytes,
                    height: 200,
                    fit: BoxFit.contain,
                  );
                });
              },
            ),
            IconButton(
              icon: const Icon(Icons.repeat_outlined),
              tooltip: 'Encode Demo 2',
              onPressed: () async {
                final bytes = await rootBundle.load("assets/keyboard.png");
                final avifBytes = await encodeAvif(bytes.buffer.asUint8List());
                setState(() {
                  encoderOutput2 = AvifImage.memory(
                    avifBytes,
                    height: 200,
                    fit: BoxFit.contain,
                  );
                });
              },
            ),
          ],
        ),
        body: ListView(
          children: [
            AvifImage.asset(
              "assets/vettel.avif",
              height: 200,
              fit: BoxFit.contain,
            ),
            AvifImage.network(
              "https://ezgif.com/images/format-demo/butterfly.avif",
              height: 200,
              fit: BoxFit.contain,
            ),
            encoderOutput,
            encoderOutput2,
          ],
        ),
      ),
    );
  }
}

以上内容涵盖了 flutter_avif 插件的主要功能及其使用方法。希望这对你有所帮助!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter AVIF图像格式支持插件flutter_avif的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter AVIF图像格式支持插件flutter_avif的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成和使用flutter_avif插件来支持AVIF图像格式的示例代码。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加flutter_avif插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_avif: ^0.x.x  # 请确保使用最新版本,这里用0.x.x表示

然后运行flutter pub get来安装依赖。

2. 导入插件

在你需要使用AVIF图像的Dart文件中导入插件:

import 'package:flutter_avif/flutter_avif.dart';

3. 使用AVIF图像

3.1. 从文件加载AVIF图像

你可以使用FlutterAvif.decodeFile方法从文件中解码AVIF图像:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_avif/flutter_avif.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('AVIF Example'),
        ),
        body: Center(
          child: FutureBuilder<Uint8List?>(
            future: _loadAvifImage(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return Text('Error loading AVIF image: ${snapshot.error}');
                } else if (snapshot.data != null) {
                  final imageProvider = MemoryImage(snapshot.data!);
                  return Image(image: imageProvider);
                }
              }
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }

  Future<Uint8List?> _loadAvifImage() async {
    final file = File('path/to/your/image.avif');
    try {
      final avifData = await file.readAsBytes();
      final decodedImage = await FlutterAvif.decodeFile(avifData);
      return decodedImage;
    } catch (e) {
      print('Error decoding AVIF: $e');
      return null;
    }
  }
}

注意:请将'path/to/your/image.avif'替换为你的AVIF图像文件的实际路径。

3.2. 从内存加载AVIF图像

如果你已经有AVIF图像的字节数据,你可以直接使用FlutterAvif.decodeBytes方法:

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_avif/flutter_avif.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final avifBytes = Uint8List.fromList(/* 你的AVIF字节数据 */);

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('AVIF Example'),
        ),
        body: Center(
          child: FutureBuilder<Uint8List?>(
            future: _decodeAvifImage(avifBytes),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return Text('Error decoding AVIF image: ${snapshot.error}');
                } else if (snapshot.data != null) {
                  final imageProvider = MemoryImage(snapshot.data!);
                  return Image(image: imageProvider);
                }
              }
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }

  Future<Uint8List?> _decodeAvifImage(Uint8List avifBytes) async {
    try {
      final decodedImage = await FlutterAvif.decodeBytes(avifBytes);
      return decodedImage;
    } catch (e) {
      print('Error decoding AVIF: $e');
      return null;
    }
  }
}

在这个例子中,你需要将Uint8List.fromList(/* 你的AVIF字节数据 */)替换为实际的AVIF字节数据。

4. 运行项目

完成上述步骤后,你可以运行你的Flutter项目来查看AVIF图像是否正确加载和显示。

flutter run

这样,你就可以在Flutter项目中成功使用flutter_avif插件来支持AVIF图像格式了。

回到顶部