Flutter图像滤镜处理插件flutter_core_image_filters的使用
Flutter图像滤镜处理插件flutter_core_image_filters的使用
描述
flutter_core_image_filters
是一个用于iOS和MacOS平台的Flutter包,它允许开发者应用CoreImage滤镜到图片上。这个插件支持大量的CoreImage滤镜,并且可以方便地集成到Flutter项目中。
使用方法
导出处理后的图片
要导出处理后的图片,首先需要指定输入源和配置滤镜参数。以下是一个简单的例子:
final inputSource = AssetInputSource('demo.jpeg');
final configuration = CIPhotoEffectChromeConfiguration();
final image = await configuration.export(inputSource);
CIImagePreview 示例
为了实时预览滤镜效果,可以使用 CIImagePreview
组件。下面的例子展示了如何创建一个包含滤镜预览页面的应用程序:
import 'package:flutter_core_image_filters/flutter_core_image_filters.dart';
class PreviewPage extends StatefulWidget {
const PreviewPage({Key? key}) : super(key: key);
@override
State<PreviewPage> createState() => _PreviewPageState();
}
class _PreviewPageState extends State<PreviewPage> {
late CIPhotoEffectChromeConfiguration configuration;
late final CIImagePreviewController controller;
bool controllerReady = false;
@override
void initState() {
super.initState();
_prepare().whenComplete(() {
setState(() {});
});
}
Future<void> _prepare() async {
configuration = CIPhotoEffectChromeConfiguration();
controller = await CIImagePreviewController.fromAsset(_assetPath);
await configuration.prepare();
await controller.connect(configuration);
controllerReady = true;
}
@override
void dispose() {
controller.dispose();
configuration.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return controllerReady
? CIImagePreview(controller: controller)
: const Offstage();
}
}
分割预览示例
如果你想同时展示原图和处理后的对比效果,可以使用 BeforeAfter
组件来实现分割预览功能:
import 'package:before_after_image_slider_nullsafty/before_after_image_slider_nullsafty.dart';
import 'package:flutter_core_image_filters/flutter_core_image_filters.dart';
class DividedPreviewPage extends StatefulWidget {
const DividedPreviewPage({Key? key}) : super(key: key);
@override
State<DividedPreviewPage> createState() => _DividedPreviewPageState();
}
class _DividedPreviewPageState extends State<DividedPreviewPage> {
late CIPhotoEffectChromeConfiguration configuration;
late final CIImagePreviewController sourceController;
late final CIImagePreviewController destinationController;
bool controllersReady = false;
@override
void initState() {
super.initState();
_prepare().whenComplete(() {
setState(() {});
});
}
Future<void> _prepare() async {
configuration = CIPhotoEffectChromeConfiguration();
sourceController = await CIImagePreviewController.fromAsset('demo.jpeg');
destinationController = await CIImagePreviewController.fromAsset('demo.jpeg');
await configuration.prepare();
await destinationController.connect(configuration);
controllersReady = true;
}
@override
void dispose() {
sourceController.dispose();
destinationController.dispose();
configuration.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return controllersReady
? BeforeAfter(
thumbRadius: 0.0,
thumbColor: Colors.transparent,
beforeImage: CIImagePreview(
controller: sourceController,
),
afterImage: CIImagePreview(
controller: destinationController,
),
)
: const Offstage();
}
}
导出并保存处理后的图片
如果你想要将处理后的图片保存到本地存储,可以通过如下代码实现:
import 'package:image/image.dart' as img;
import 'package:path_provider/path_provider.dart';
// ... 省略部分代码 ...
final directory = await getTemporaryDirectory();
final output = File('${directory.path}/result.jpeg');
final bytes = await image.toByteData();
final persistedImage = img.Image.fromBytes(
width: image.width,
height: image.height,
bytes: bytes!.buffer,
numChannels: 4,
);
img.JpegEncoder encoder = img.JpegEncoder();
final data = encoder.encode(persistedImage);
await output.writeAsBytes(data);
核心图像滤镜支持状态
下表列出了当前版本支持的部分CoreImage滤镜:
状态 | 名称 | 显示名称 |
---|---|---|
✅ | CIAccordionFoldTransition | Accordion Fold Transition |
✅ | CIAreaAverage | Area Average |
✅ | CIAreaHistogram | Area Histogram |
✅ | CIAreaLogarithmicHistogram | Area Logarithmic Histogram |
…(更多内容请参阅官方文档)
示例结果
以下是几种不同滤镜的效果截图:
…
完整示例
你可以查看 Big Flutter Filters Demo 来获取更详细的用法示例。
维护者
希望这些信息对你有所帮助!如果你有任何问题或需要进一步的帮助,请随时提问。
更多关于Flutter图像滤镜处理插件flutter_core_image_filters的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图像滤镜处理插件flutter_core_image_filters的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用flutter_core_image_filters
插件来处理图像滤镜的一个示例。这个插件提供了一系列核心的图像滤镜,类似于iOS的Core Image框架。
首先,确保你已经在pubspec.yaml
文件中添加了flutter_core_image_filters
依赖:
dependencies:
flutter:
sdk: flutter
flutter_core_image_filters: ^0.1.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
接下来是一个完整的示例代码,展示如何使用flutter_core_image_filters
应用不同的图像滤镜:
import 'package:flutter/material.dart';
import 'package:flutter_core_image_filters/flutter_core_image_filters.dart';
import 'dart:ui' as ui;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ImageFilterScreen(),
);
}
}
class ImageFilterScreen extends StatefulWidget {
@override
_ImageFilterScreenState createState() => _ImageFilterScreenState();
}
class _ImageFilterScreenState extends State<ImageFilterScreen> {
final String imageUrl = 'https://via.placeholder.com/600'; // 替换为你的图像URL
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Core Image Filters Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ImageFilteredNetworkImage(
imageUrl: imageUrl,
filter: ui.ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
),
SizedBox(height: 20),
ImageFilteredNetworkImage(
imageUrl: imageUrl,
filter: ui.ImageFilter.matrix(
[
1, 0, 0, 0, 0, // Red scale
0, 0, 0, 0, 0, // Green ignored
0, 0, 1, 0, 0, // Blue scale
0, 0, 0, 1, 0, // Alpha unchanged
],
),
),
SizedBox(height: 20),
ImageFilteredNetworkImage(
imageUrl: imageUrl,
filter: ui.ImageFilter.grayscale(1.0),
),
],
),
),
);
}
}
class ImageFilteredNetworkImage extends StatefulWidget {
final String imageUrl;
final ui.ImageFilter filter;
const ImageFilteredNetworkImage({Key key, @required this.imageUrl, @required this.filter}) : super(key: key);
@override
_ImageFilteredNetworkImageState createState() => _ImageFilteredNetworkImageState();
}
class _ImageFilteredNetworkImageState extends State<ImageFilteredNetworkImage> {
ImageProvider _imageProvider;
@override
void initState() {
super.initState();
_imageProvider = NetworkImage(widget.imageUrl);
preloadImage(context, _imageProvider).then((_) {
setState(() {});
});
}
Future<void> preloadImage(BuildContext context, ImageProvider image) async {
final Completer<void> completer = Completer<void>();
final ImageStreamListener listener = ImageStreamListener((ImageInfo imageInfo, bool synchronousCall) {
completer.complete();
imageInfo.dispose();
});
final ImageStream imageStream = image.resolve(createLocalImageConfiguration(context));
imageStream.addListener(listener);
return completer.future;
}
@override
Widget build(BuildContext context) {
return RepaintBoundary(
child: CustomPaint(
painter: ImageFilterPainter(_imageProvider, widget.filter),
size: Size.infinite, // This ensures the painter paints over the entire available space
),
);
}
}
class ImageFilterPainter extends CustomPainter {
final ImageProvider imageProvider;
final ui.ImageFilter filter;
ImageFilterPainter(this.imageProvider, this.filter);
@override
void paint(Canvas canvas, Size size) async {
final paint = Paint();
final image = await _loadImage(imageProvider);
final filteredImage = await _applyFilter(image, filter);
canvas.drawImage(filteredImage, Offset.zero, paint);
}
Future<ui.Image> _loadImage(ImageProvider imageProvider) async {
final completer = Completer<ui.Image>();
imageProvider.resolve(ImageConfiguration()).addListener(
ImageStreamListener(
(ImageInfo imageInfo, bool synchronousCall) async {
final ui.Image image = imageInfo.image;
if (!mounted) return;
completer.complete(image);
imageInfo.dispose();
},
),
);
return completer.future;
}
Future<ui.Image> _applyFilter(ui.Image image, ui.ImageFilter filter) async {
final recorder = ui.PictureRecorder();
final canvas = Canvas(recorder);
final paint = Paint();
canvas.drawImage(image, Offset.zero, paint);
final picture = recorder.endRecording();
final sceneBuilder = ui.SceneBuilder();
sceneBuilder.addPicture(Offset.zero, picture);
final layerTree = sceneBuilder.build();
final filterLayer = ui.ImageFilterLayer(filter, layerTree);
final scene = ui.Scene(filterLayer);
final imageRecorder = ui.PictureRecorder();
final sceneCanvas = Canvas(imageRecorder);
scene.rasterize(sceneCanvas);
final filteredPicture = imageRecorder.endRecording();
final filteredImage = await filteredPicture.toImage();
return filteredImage;
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true; // In a real-world scenario, implement a more efficient repaint logic
}
}
解释
-
依赖安装:在
pubspec.yaml
中添加flutter_core_image_filters
依赖。 -
ImageFilterScreen:主屏幕组件,展示三种不同的滤镜效果(模糊、红通道、灰度)。
-
ImageFilteredNetworkImage:自定义组件,用于加载网络图片并应用滤镜。
-
ImageFilterPainter:自定义
CustomPainter
,用于在画布上绘制经过滤镜处理的图像。 -
_loadImage:异步加载图像。
-
_applyFilter:应用滤镜并返回处理后的图像。
请注意,ImageFilterPainter
中的shouldRepaint
方法返回true
,这意味着每次构建都会重新绘制。在实际应用中,你可能需要实现更高效的逻辑来避免不必要的重绘。
希望这个示例代码能帮助你理解如何在Flutter中使用flutter_core_image_filters
插件来处理图像滤镜。