Flutter计算机视觉插件dart_cva的使用
Flutter 计算机视觉插件 dart_cva 的使用
dart_cva
是一个用于通过类管理组件变体的工具。它是流行的 CVA(Class Variance Authority)库的 Dart 移植版本,由 Joe Bell 创建。它提供了类型安全且灵活的方式来管理组件变体,特别适用于样式系统和组件库。如果你正在使用 jaspr
和 jaspr_tailwind
构建和样式化反应式用户界面,dart_cva
可以无缝集成!🚀
功能
- 类型安全的变体管理
- 支持组合变体
- 默认变体配置
- 额外的类合并
- 全面的变体组合生成
- 无依赖
- 框架无关,适合
jaspr
和jaspr_tailwind
安装
要在项目中使用该包,请在 pubspec.yaml
文件中添加以下依赖:
dependencies:
dart_cva: ^1.0.0
使用
基本示例
import 'package:dart_cva/dart_cva.dart';
final buttonCva = cva(
base: ['button', 'font-semibold'], // 应用于所有变体的基本类
variants: {
'type': {
'primary': 'bg-blue-500 text-white hover:bg-blue-600',
'secondary': 'bg-gray-200 text-gray-900 hover:bg-gray-300',
},
'size': {
'sm': 'text-sm px-2 py-1',
'md': 'text-base px-3 py-2',
'lg': 'text-lg px-4 py-2',
},
},
defaultVariants: {
'type': 'primary',
'size': 'md',
},
);
void main() {
print(buttonCva()); // 使用默认值: 'button font-semibold bg-blue-500 text-white hover:bg-blue-600 text-base px-3 py-2'
print(buttonCva({'type': 'secondary', 'size': 'lg'})); // 自定义变体: 'button font-semibold bg-gray-200 text-gray-900 hover:bg-gray-300 text-lg px-4 py-2'
}
组合变体
组合变体允许你在多个条件满足时应用额外的类。
final buttonCva = cva(
base: ['button'],
variants: {
'type': {
'primary': 'bg-blue-500',
'secondary': 'bg-gray-200',
},
'size': {
'sm': 'text-sm',
'lg': 'text-lg',
},
},
compoundVariants: [
{
'type': 'primary',
'size': 'lg',
'class': 'uppercase tracking-wider',
},
],
);
// 当 type 为 'primary' 并且 size 为 'lg' 时,uppercase 和 tracking-wider 类将被应用
print(
buttonCva({
'type': 'primary',
'size': 'lg',
}),
);
变体组合
getAllVariantCombinations()
方法是一个强大的工具,可以生成所有可能的变体组合。这在测试所有可能的变体状态、生成文档、创建组件展示或进行视觉回归测试时非常有用。
// 使用 cva 定义按钮样式
final buttonStyles = cva(
base: ['button'], // 应用于所有变体的基本类
variants: {
'type': {
'primary': 'bg-blue-500', // 主类型样式
'secondary': 'bg-gray-200', // 次类型样式
},
'size': {
'sm': 'text-sm', // 小尺寸样式
'lg': 'text-lg', // 大尺寸样式
},
},
);
void main() {
// 获取所有可能的变体组合
final combinations = buttonStyles.getAllVariantCombinations();
// 打印生成的组合
print(combinations);
// 迭代每个组合以渲染所有变体
for (final combo in combinations) {
print('变体: $combo'); // 打印当前变体组合
print('类: ${buttonStyles(combo)}'); // 打印当前组合的类
}
}
额外的类
你可以使用特殊的 ‘class’ 键添加额外的类。
print(
buttonCva({
'type': 'primary',
'class': 'custom-class another-class',
}),
);
框架集成
Jaspr
import 'package:jaspr/jaspr.dart';
import 'package:dart_cva/dart_cva.dart';
// 按钮类型的枚举,带有关联的类
// 枚举通过限制值为预定义选项来提供更多的类型安全性
enum CvaButtonType {
primary('bg-emerald-600 text-white hover:bg-emerald-700'),
secondary('bg-gray-200 text-gray-900 hover:bg-gray-300'),
danger('bg-red-600 text-white hover:bg-red-700'),
plain('bg-transparent text-white hover:bg-white hover:text-gray-900');
final String classes;
const CvaButtonType(this.classes);
}
// 按钮大小的枚举,带有关联的类
// 枚举确保只使用有效的大小,增强类型安全性
enum ButtonSize {
sm('h-8 px-3 text-sm'),
md('h-10 px-4 text-base'),
lg('h-12 px-6 text-lg');
final String classes;
const ButtonSize(this.classes);
}
// 使用 cva 定义按钮样式
final buttonStyles = cva(
base: [
'inline-flex',
'items-center',
'justify-center',
'rounded-full',
'font-medium',
'transition-colors'
],
variants: {
'type': {
for (final type in CvaButtonType.values) type.name: type.classes,
},
'size': {
for (final size in ButtonSize.values) size.name: size.classes,
},
'fullWidth': {
'true': 'w-full',
'false': '',
},
},
defaultVariants: {
'type': CvaButtonType.primary.name,
'size': ButtonSize.lg.name,
'fullWidth': 'false',
},
compoundVariants: [
{
'type': 'primary',
'size': 'lg',
'class': 'font-bold',
},
{
'disabled': 'true',
'class': 'opacity-50 cursor-not-allowed',
},
],
);
// 按钮组件类
class Button extends StatelessComponent {
final CvaButtonType? type; // 按钮类型
final ButtonSize? size; // 按钮大小
final bool? fullWidth; // 全宽度标志
final String? classes; // 额外的类
final List<Component> children; // 子组件
final void Function()? onClick; // 点击事件处理程序
final bool disabled; // 禁用状态
Button(
this.children, {
super.key,
this.type,
this.size,
this.fullWidth,
this.classes,
this.onClick,
this.disabled = false,
});
[@override](/user/override)
Iterable<Component> build(BuildContext context) sync* {
yield button(
events: events(
onClick: (onClick != null && !disabled) ? onClick : null,
),
classes: buttonStyles({
'type': type?.name,
'size': size?.name,
'fullWidth': fullWidth?.toString(),
'class': classes,
}),
disabled: disabled,
children,
);
}
}
// 使用示例
// 在 ShowCase 无状态组件内部使用 Button 组件
class ShowCase extends StatelessComponent {
[@override](/user/override)
Iterable<Component> build(BuildContext context) sync* {
yield Button(
[
Text('点击我'),
],
type: CvaButtonType.primary,
size: ButtonSize.md,
fullWidth: true,
classes: 'custom-class',
onClick: () {
print('按钮已点击!');
},
disabled: false,
);
}
}
更多关于Flutter计算机视觉插件dart_cva的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter计算机视觉插件dart_cva的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
dart_cva
是一个用于在 Flutter 应用中实现计算机视觉功能的 Dart 插件。它基于 OpenCV,提供了对图像处理、特征提取、对象检测等功能的支持。以下是如何在 Flutter 项目中使用 dart_cva
插件的基本步骤。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 dart_cva
插件的依赖:
dependencies:
flutter:
sdk: flutter
dart_cva: ^0.0.1 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
2. 导入库
在你的 Dart 文件中导入 dart_cva
库:
import 'package:dart_cva/dart_cva.dart';
3. 初始化 Cva
实例
在使用 dart_cva
之前,你需要初始化一个 Cva
实例:
final cva = Cva();
4. 加载图像
你可以从不同的源加载图像,例如文件、网络或内存中的图像数据。以下是加载本地文件中的图像的示例:
final image = await cva.loadImageFromPath('path/to/your/image.jpg');
5. 图像处理
dart_cva
提供了一系列图像处理功能。例如,你可以将图像转换为灰度图:
final grayImage = await cva.convertToGray(image);
6. 特征提取
你可以使用 dart_cva
进行特征提取,例如边缘检测:
final edges = await cva.cannyEdgeDetection(grayImage, threshold1: 100, threshold2: 200);
7. 对象检测
dart_cva
也支持对象检测功能。你需要加载预训练的模型文件,然后进行检测:
final model = await cva.loadModel('path/to/your/model.xml');
final detections = await cva.detectObjects(image, model);
8. 显示结果
你可以在 Flutter 应用中显示处理后的图像或检测结果。例如,你可以使用 Image
组件显示图像:
Image.memory(
await cva.imageToBytes(grayImage),
fit: BoxFit.cover,
)
9. 释放资源
在使用完 dart_cva
之后,记得释放相关资源:
cva.dispose();
示例代码
以下是一个完整的示例代码,展示了如何使用 dart_cva
进行图像灰度化处理并显示结果:
import 'package:flutter/material.dart';
import 'package:dart_cva/dart_cva.dart';
class ImageProcessingPage extends StatefulWidget {
[@override](/user/override)
_ImageProcessingPageState createState() => _ImageProcessingPageState();
}
class _ImageProcessingPageState extends State<ImageProcessingPage> {
Cva cva = Cva();
Uint8List? processedImage;
[@override](/user/override)
void initState() {
super.initState();
_processImage();
}
Future<void> _processImage() async {
final image = await cva.loadImageFromPath('path/to/your/image.jpg');
final grayImage = await cva.convertToGray(image);
setState(() {
processedImage = grayImage;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Processing'),
),
body: Center(
child: processedImage != null
? Image.memory(
processedImage!,
fit: BoxFit.cover,
)
: CircularProgressIndicator(),
),
);
}
[@override](/user/override)
void dispose() {
cva.dispose();
super.dispose();
}
}