Flutter图像模糊预览插件fast_blurhash的使用
Flutter图像模糊预览插件 fast_blurhash
的使用
fast_blurhash
是一个利用 Rust 解码 BlurHash 并使用 Dart FFI 调用这些函数的 Dart 包。相比常见的 Dart 实现,它平均快 20 倍以上,并且可以在发布模式下通过运行 benchmarks.dart
演示来测试其性能。
状态
- 使用实验性 API,未来可能会有所更改。
- 第一次调用需要更长时间,因此添加了一个设置函数进行预热调用。
- 仅在 iOS 和 MacOS 上的发布模式中进行了测试。
- 发布模式和调试模式之间的性能差异显著,请勿依赖调试模式的结果。
项目结构
rust
: 包含 Rust 源代码。lib
: 包含定义插件 API 的 Dart 代码,并使用dart:ffi
调用本地代码。
性能基准测试
为了在发布模式下测试包的性能,可以运行 benchmarks.dart
演示:
flutter run -t lib/benchmarks.dart --release
iPhone 15 Pro 示例截图
M1 MacBook Pro 示例截图
示例 Demo
以下是完整的示例代码,展示了如何使用 fast_blurhash
插件:
import 'dart:typed_data';
import 'package:fast_blurhash/fast_blurhash.dart';
import 'package:flutter/material.dart';
void main() {
setup(); // 初始化预热调用
runApp(const BlurHashDemo());
}
class BlurHashDemo extends StatefulWidget {
const BlurHashDemo({super.key});
[@override](/user/override)
State<BlurHashDemo> createState() => _BlurHashDemoState();
}
class _BlurHashDemoState extends State<BlurHashDemo> {
final images = [
"https://i.imgur.com/fU8vqCi.jpeg",
"https://i.imgur.com/2CXbtO9.jpeg",
"https://i.imgur.com/54sDohv.jpeg",
];
final hashes = [
"THEC,t~qWGb=IUxI%ejEIBR~xuaf",
"TKLpT@?w=V_3RkH=10IU,nT1NGn4",
"TgDSt8kDWV~qt7WV_3s:ay?bofj@",
];
bool useAsync = false;
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('BlurHash Demo'),
actions: [
Switch(
value: useAsync,
onChanged: (value) {
setState(() {
useAsync = value;
});
},
),
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Center(
child: Text(useAsync ? 'Async' : 'Sync'),
),
),
],
),
body: PageView.builder(
scrollDirection: Axis.vertical,
itemCount: images.length,
itemBuilder: (BuildContext context, int index) {
if (useAsync) {
return FastBlurhashWidgetBuilder(blurhashString: hashes[index]);
}
return SizedBox.expand(
child: FadeInImage.memoryNetwork(
fit: BoxFit.cover,
placeholder: decodeBlurhash(blurhashString: hashes[index]),
fadeInDuration: const Duration(seconds: 2),
fadeOutDuration: const Duration(seconds: 2),
image: images[index],
),
);
},
),
),
);
}
}
class FastBlurhashWidgetBuilder extends StatefulWidget {
const FastBlurhashWidgetBuilder({
super.key,
required this.blurhashString,
this.height = 32,
this.width = 32,
this.punch = 1.0,
this.enableCache = true,
this.child,
});
final String blurhashString;
final int height;
final int width;
final double punch;
final bool enableCache;
final Widget? child;
[@override](/user/override)
State<FastBlurhashWidgetBuilder> createState() =>
_FastBlurhashWidgetBuilderState();
}
class _FastBlurhashWidgetBuilderState extends State<FastBlurhashWidgetBuilder> {
late Future<Uint8List> _blurhashFuture;
[@override](/user/override)
void initState() {
super.initState();
_blurhashFuture = decodeBlurhashIsolate(
blurhashString: widget.blurhashString,
height: widget.height,
width: widget.width,
punch: widget.punch,
enableCache: widget.enableCache,
);
}
[@override](/user/override)
Widget build(BuildContext context) {
return FutureBuilder<Uint8List>(
future: _blurhashFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
return Stack(
children: [
Image.memory(
snapshot.data!,
fit: BoxFit.cover,
width: double.infinity,
height: double.infinity,
),
if (widget.child != null) widget.child!,
],
);
} else {
return widget.child ?? Container(color: Colors.transparent);
}
},
);
}
}
更多关于Flutter图像模糊预览插件fast_blurhash的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图像模糊预览插件fast_blurhash的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用fast_blurhash
插件来实现图像模糊预览的示例代码。fast_blurhash
是一个用于生成和显示Blurhash图像的插件,Blurhash是一种用于快速生成和渲染模糊图像的技术,常用于图像加载时的占位符。
首先,你需要在你的pubspec.yaml
文件中添加fast_blurhash
依赖:
dependencies:
flutter:
sdk: flutter
fast_blurhash: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来是一个完整的Flutter应用程序示例,展示了如何使用fast_blurhash
来显示Blurhash图像:
import 'package:flutter/material.dart';
import 'package:fast_blurhash/fast_blurhash.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Fast Blurhash Example'),
),
body: Center(
child: BlurhashExample(),
),
),
);
}
}
class BlurhashExample extends StatefulWidget {
@override
_BlurhashExampleState createState() => _BlurhashExampleState();
}
class _BlurhashExampleState extends State<BlurhashExample> {
String blurHashString = "LDBBARNB+w0yxpy1+VmUXgp9uQ0D"; // 示例Blurhash字符串
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BlurhashImage(
blurHash: blurHashString,
image: NetworkImage('https://example.com/path/to/your/image.jpg'), // 替换为你的图像URL
width: 300,
height: 200,
placeholderWidget: Container(
color: Colors.grey.shade200,
),
),
SizedBox(height: 20),
Text('Blurhash: $blurHashString'),
],
);
}
}
// 自定义BlurhashImage组件,用于显示Blurhash占位符和加载真实图像
class BlurhashImage extends StatefulWidget {
final String blurHash;
final ImageProvider image;
final double width;
final double height;
final Widget placeholderWidget;
BlurhashImage({
required this.blurHash,
required this.image,
required this.width,
required this.height,
this.placeholderWidget = const SizedBox.shrink(),
});
@override
_BlurhashImageState createState() => _BlurhashImageState();
}
class _BlurhashImageState extends State<BlurhashImage> {
bool isImageLoaded = false;
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
if (!isImageLoaded)
Blurhash(
hash: widget.blurHash,
width: widget.width,
height: widget.height,
child: widget.placeholderWidget,
),
Positioned.fill(
child: Image(
image: widget.image,
width: widget.width,
height: widget.height,
fit: BoxFit.cover,
loadingBuilder: (BuildContext context, Widget child, ImageInfo? imageInfo, Widget? placeholder) {
if (imageInfo == null) {
return placeholder;
}
setState(() {
isImageLoaded = true;
});
return child;
},
),
),
],
);
}
}
在这个示例中,我们定义了一个BlurhashImage
组件,它首先显示一个Blurhash占位符,当真实图像加载完成时,将Blurhash占位符替换为真实图像。Blurhash
组件用于渲染Blurhash字符串,而Image
组件用于加载和显示真实图像。
请注意,你需要将示例Blurhash字符串和图像URL替换为你自己的值。
希望这个示例对你有所帮助!