Flutter图像生成插件flutter_stable_diffusion_core_ml的使用
Flutter图像生成插件flutter_stable_diffusion_core_ml
的使用
flutter_stable_diffusion_core_ml
是一个用于在 macOS 和 iOS 平台上实现 Stable Diffusion 图像生成功能的 Flutter 插件。该插件基于 Apple 提供的 ml-stable-diffusion 实现。
使用方法
此插件已被 Flutter 官方推荐为 endorsed federated plugin,这意味着你可以直接使用 flutter_stable_diffusion
而无需手动添加到 pubspec.yaml
文件中。当使用时,它会自动包含在你的项目中。
然而,如果你需要导入此包以直接使用其 API,则仍需将其添加到 pubspec.yaml
文件中。
示例代码
以下是一个完整的示例代码,展示如何使用 flutter_stable_diffusion_core_ml
插件进行图像生成。
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_stable_diffusion_platform_interface/flutter_stable_diffusion_platform_interface.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _status = 'idle'; // 当前状态
late final TextEditingController _promptTextController =
TextEditingController(); // 提示文本控制器
late final TextEditingController _negativePromptTextController =
TextEditingController(); // 负提示文本控制器
late final TextEditingController _stepCountTextController =
TextEditingController(text: "20"); // 步骤数控制器
late final TextEditingController _scaleTextController =
TextEditingController(text: "7.5"); // 指导比例控制器
List<int>? _imageData; // 生成图像的数据
bool _isLoaded = false; // 是否加载模型
bool _generateing = false; // 是否正在生成
bool _cancelGenerateing = false; // 是否取消生成
ValueNotifier<String> _generateProgressValue =
ValueNotifier<String>(''); // 生成进度通知器
PlatformStableDiffusionPipeline? _pipline; // 管道实例
PlatformStableDiffusionPipelineGenerateCancelToken? _cancelToken; // 取消令牌
[@override](/user/override)
void initState() {
super.initState();
}
/// 开始生成图像
void tapGenerate() async {
if (_pipline == null ||
_isLoaded == false ||
_promptTextController.text.isEmpty) {
return;
}
try {
setState(() {
_generateing = true;
_cancelGenerateing = false;
_status = 'generating';
});
_generateProgressValue.value = 'generating';
_cancelToken = StableDiffusionPlatformInterface.instance!
.createPlatformPipelineGenerateCancelToken();
var result = await _pipline!.generate(
PlatformStableDiffusionPipelineGenerateParams(
prompt: _promptTextController.text,
negativePrompt: _negativePromptTextController.text,
stepCount: int.parse(_stepCountTextController.text),
guidanceScale: double.parse(_scaleTextController.text),
),
onProgress: (progress) async {
_generateProgressValue.value =
"${progress.step}/${progress.stepCount}";
},
cancelToken: _cancelToken,
);
if (result.isSuccess) {
setState(() {
_generateing = false;
_cancelGenerateing = false;
_imageData = result.imageData;
_status = 'Success';
});
} else if (result.isCancelled) {
setState(() {
_generateing = false;
_cancelGenerateing = false;
_status = 'Cancelled';
});
} else {
setState(() {
_generateing = false;
_cancelGenerateing = false;
_status = '${result.message}';
});
}
} catch (e) {
await _cancelToken?.cancel();
setState(() {
_generateing = false;
_cancelGenerateing = false;
_status = 'generate fail, $e';
});
}
}
/// 取消生成
void tapCancel() async {
setState(() {
_cancelGenerateing = true;
_status = 'cancelling';
});
_cancelToken?.cancel();
}
/// 构建生成控件
Widget buildGenerateWidgets(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Prompts", style: TextStyle(fontWeight: FontWeight.bold)),
const SizedBox(height: 4),
Container(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(4),
),
height: 38,
alignment: Alignment.centerLeft,
child: TextField(
controller: _promptTextController,
decoration: const InputDecoration(
isDense: true,
border: InputBorder.none,
hintText: 'prompt',
),
),
),
const SizedBox(height: 4),
Container(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(4),
),
height: 38,
alignment: Alignment.centerLeft,
child: TextField(
controller: _negativePromptTextController,
decoration: const InputDecoration(
isDense: true,
border: InputBorder.none,
hintText: 'negative prompt',
),
),
),
const Divider(),
Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(4),
),
height: 38,
alignment: Alignment.centerLeft,
child: TextField(
controller: _stepCountTextController,
keyboardType:
const TextInputType.numberWithOptions(decimal: false),
onChanged: (text) {
if (text.isEmpty) {
_stepCountTextController.value = const TextEditingValue(
text: "1",
selection:
TextSelection(baseOffset: 0, extentOffset: 1),
);
}
},
decoration: const InputDecoration(
isDense: true,
border: InputBorder.none,
prefix: Text("step count:"),
),
),
),
),
Container(
width: 1,
color: Theme.of(context).dividerColor,
height: 28,
margin: const EdgeInsets.symmetric(horizontal: 4),
),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(4),
),
height: 38,
alignment: Alignment.centerLeft,
child: TextField(
controller: _scaleTextController,
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
onChanged: (text) {
if (text.isEmpty) {
_scaleTextController.value = const TextEditingValue(
text: "1",
selection:
TextSelection(baseOffset: 0, extentOffset: 1),
);
}
},
decoration: const InputDecoration(
isDense: true,
border: InputBorder.none,
prefix: Text("guidance scale:"),
hintText: '',
),
),
),
),
],
),
Row(
children: [
Expanded(
child: TextButton(
onPressed:
!_generateing && !_cancelGenerateing ? tapGenerate : null,
child: const Text("Generate"),
),
),
Expanded(
child: TextButton(
onPressed:
_generateing && !_cancelGenerateing ? tapCancel : null,
child: const Text("Cancel"),
),
),
],
),
ValueListenableBuilder(
valueListenable: _generateProgressValue,
builder: (context, value, child) {
return Text(value);
},
),
],
);
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TextButton(
onPressed: () async {
try {
var result = await FilePicker.platform.getDirectoryPath();
if (result != null) {
setState(() {
_isLoaded = false;
_status = 'loading';
});
await _cancelToken?.cancel();
await _pipline?.dispose();
_pipline = StableDiffusionPlatformInterface.instance!
.createPlatformPipeline(
PlatformStableDiffusionPipelineCreationParams(
modelPath: result),
);
await _pipline?.loadResources();
setState(() {
_isLoaded = true;
_status = 'loaded';
});
}
} catch (e) {
setState(() {
_status = 'model load fail, $e';
_pipline = null;
_isLoaded = false;
});
}
},
child: const Text("picker model"),
),
if (_imageData != null)
Image.memory(Uint8List.fromList(_imageData!)),
Text('current status: $_status\n'),
if (_isLoaded) buildGenerateWidgets(context),
],
),
),
),
);
}
}
更多关于Flutter图像生成插件flutter_stable_diffusion_core_ml的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图像生成插件flutter_stable_diffusion_core_ml的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_stable_diffusion_core_ml
是一个 Flutter 插件,用于在 iOS 设备上使用 Core ML 框架运行 Stable Diffusion 模型来生成图像。这个插件允许你在 Flutter 应用中集成 AI 图像生成功能。
安装插件
首先,你需要在 pubspec.yaml
文件中添加 flutter_stable_diffusion_core_ml
插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_stable_diffusion_core_ml: ^0.0.1 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
配置 iOS 项目
由于这个插件依赖于 Core ML,因此它只能在 iOS 设备上运行。你需要确保你的 iOS 项目已经正确配置。
-
启用 Core ML 支持:在 Xcode 中打开你的 iOS 项目,确保
CoreML.framework
已经添加到Linked Frameworks and Libraries
中。 -
添加模型文件:你需要将 Stable Diffusion 的 Core ML 模型文件(通常是
.mlmodel
文件)添加到你的 Xcode 项目中。确保模型文件被正确包含在Copy Bundle Resources
中。
使用插件
在你的 Flutter 代码中,你可以使用 flutter_stable_diffusion_core_ml
插件来生成图像。以下是一个简单的示例:
import 'package:flutter/material.dart';
import 'package:flutter_stable_diffusion_core_ml/flutter_stable_diffusion_core_ml.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Stable Diffusion Example'),
),
body: Center(
child: ImageGenerator(),
),
),
);
}
}
class ImageGenerator extends StatefulWidget {
[@override](/user/override)
_ImageGeneratorState createState() => _ImageGeneratorState();
}
class _ImageGeneratorState extends State<ImageGenerator> {
Uint8List? _generatedImage;
Future<void> _generateImage() async {
try {
final result = await FlutterStableDiffusionCoreMl.generateImage(
prompt: "A beautiful landscape with mountains and a river",
steps: 50,
guidanceScale: 7.5,
seed: 42,
);
setState(() {
_generatedImage = result;
});
} catch (e) {
print("Error generating image: $e");
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_generatedImage != null)
Image.memory(_generatedImage!)
else
Text("No image generated yet."),
SizedBox(height: 20),
ElevatedButton(
onPressed: _generateImage,
child: Text("Generate Image"),
),
],
);
}
}