Flutter高级图像绘制插件image_painter_extended的使用
Flutter高级图像绘制插件image_painter_extended的使用
这是一个允许用户在图像上进行绘制的Flutter包。它是painter2包的一个扩展,具有缩放和绘制功能。
特性
该组件支持以下功能:
- 更改前景色和背景色
- 设置背景图像
- 更改绘制路径的粗细
- 导出你的绘画为PNG格式
- 撤销/重做绘制路径
- 清除整个绘图
- 缩放和平移图像
安装
在你的Flutter项目的pubspec.yaml
文件中添加依赖:
dependencies:
image_painter_extended: any
然后导入它:
import 'package:image_painter_extended/image_painter_extended.dart';
使用
为了使用这个插件,首先创建一个控制器并可选地创建一个键:
GlobalKey<ImagePainterState> painterKey = GlobalKey<ImagePainterState>();
PainterController controller = PainterController();
controller.thickness = 5.0; // 设置画笔的粗细,默认为1.0
controller.backgroundColor = Colors.green; // 背景颜色在设置了背景图像时会被忽略
controller.backgroundImage = Image.network(...); // 设置背景图像。你可以像平常一样加载图像:从资源文件、网络或内存中加载。
该控制器将处理所有绘制空间的属性。键用于刷新小部件的状态,如果你决定以编程方式平移和缩放图像。
然后,为了显示绘制区域,创建一个内联的ImagePainter
小部件,并给它一个之前创建的控制器的引用:
ImagePainter(controller, key: painterKey)
通过导出绘画为PNG格式,你会得到一个表示最终文件字节的Uint8List对象:
await controller.getPNGBytes();
你还可以使用getPathBytes()
函数获取路径而不包含图像。
库本身不处理保存最终图像。
完整示例
下面是一个完整的示例代码,展示了如何使用image_painter_extended
插件。
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_painter_extended/image_painter_extended.dart';
import 'package:flutter_switch/flutter_switch.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: DemoPage(),
);
}
}
class DemoPage extends StatefulWidget {
[@override](/user/override)
_DemoPageState createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
Image bg = Image.asset("lib/assets/img.jpg", fit: BoxFit.cover);
GlobalKey<ImagePainterState> painterKey = GlobalKey<ImagePainterState>();
double scale = 1;
double translateX = 0;
double translateY = 0;
String savepath = "";
bool buttonCOntrol = false;
bool isDrawmode = true;
PainterController _controller;
[@override](/user/override)
void initState() {
super.initState();
_controller = _newController();
}
PainterController _newController() {
PainterController controller = new PainterController();
controller.backgroundImage = bg;
controller.thickness = 5.0;
controller.backgroundColor = Colors.transparent;
return controller;
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Container(
child: Center(
child: AspectRatio(
aspectRatio: 1.0,
child: ImagePainter(
_controller,
key: painterKey,
))),
),
Text(savepath),
Expanded(
child: SingleChildScrollView(
child: Column(children: [
Text("如何控制"),
howTOControl(),
Text("绘制选项"),
basicOptions(),
!buttonCOntrol ? Text("模式") : Container(),
!buttonCOntrol ? switchOption() : Container(),
buttonCOntrol ? Text("控制按钮") : Container(),
buttonCOntrol ? optionsBUtton() : Container(),
]))),
],
));
}
Widget howTOControl() {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("按钮模式"),
FlutterSwitch(
value: buttonCOntrol,
onToggle: (val) {
setState(() {
buttonCOntrol = val;
isDrawmode = true;
});
_controller.drawMode = true;
translateX = 0;
translateY = 0;
scale = 1;
transformMatrix();
},
),
],
);
}
Widget switchOption() {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("变换模式"),
FlutterSwitch(
value: isDrawmode,
inactiveColor: Colors.green,
onToggle: (val) {
setState(() {
isDrawmode = val;
});
_controller.drawMode = val;
painterKey.currentState.setState(() {});
},
),
Text("绘制模式"),
],
);
}
Widget basicOptions() {
return Wrap(
spacing: 10,
children: [
ElevatedButton(
onPressed: () {
_controller.undo();
},
child: Text("撤销")),
ElevatedButton(
onPressed: () {
_controller.redo();
},
child: Text("重做")),
ElevatedButton(
onPressed: () async {
final String path = (await getApplicationDocumentsDirectory()).path;
setState(() {
savepath = "Saved to " + path;
});
print(path);
// 仅保存路径
Uint8List img = await _controller.getPathBytes();
File('$path/image1.png').writeAsBytes(img);
},
child: Text("保存路径")),
ElevatedButton(
onPressed: () async {
final String path = (await getApplicationDocumentsDirectory()).path;
setState(() {
savepath = "Saved to " + path;
});
translateX = 0;
translateY = 0;
scale = 1;
transformMatrix();
await Future.delayed(Duration(milliseconds: 100), () {});
print(path);
// 保存完整图像
Uint8List pngBytes = await _controller.getPNGBytes();
File('$path/image2.png').writeAsBytes(pngBytes);
},
child: Text("保存图像")),
ElevatedButton(
onPressed: () {
_controller.clear();
},
child: Text("清除")),
],
);
}
Widget optionsBUtton() {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () {
if (scale < 2.5) {
scale += 0.5;
transformMatrix();
}
},
child: Text("+")),
ElevatedButton(
onPressed: () {
if (scale > 1) {
scale -= 0.5;
transformMatrix();
}
},
child: Text("-")),
ElevatedButton(
onPressed: () {
translateX = 0;
translateY = 0;
scale = 1;
transformMatrix();
},
child: Text("重置变换"))
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () {
translateY += 2;
transformMatrix();
},
child: Text("向上")),
ElevatedButton(
onPressed: () {
translateY -= 2;
transformMatrix();
},
child: Text("向下")),
ElevatedButton(
onPressed: () {
translateX -= 2;
transformMatrix();
},
child: Text("向左")),
ElevatedButton(
onPressed: () {
translateX += 2;
transformMatrix();
},
child: Text("向右"))
],
),
],
);
}
void transformMatrix() {
_controller.interactionController.value = Matrix4(
scale,
0,
0,
0,
0,
scale,
0,
0,
0,
0,
1,
0,
translateX,
translateY,
0,
1,
);
painterKey.currentState.setState(() {});
}
}
更多关于Flutter高级图像绘制插件image_painter_extended的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter高级图像绘制插件image_painter_extended的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用image_painter_extended
插件进行高级图像绘制的示例代码。image_painter_extended
插件提供了一些高级功能,允许你在Canvas上进行复杂的图像绘制操作。
首先,确保你已经在pubspec.yaml
文件中添加了image_painter_extended
依赖:
dependencies:
flutter:
sdk: flutter
image_painter_extended: ^最新版本号 # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
以下是一个简单的示例,展示了如何使用image_painter_extended
在Flutter应用中绘制一张图片并进行一些基本的变换操作:
import 'package:flutter/material.dart';
import 'package:image_painter_extended/image_painter_extended.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Image Painter Extended Example'),
),
body: CustomPaint(
size: Size(double.infinity, double.infinity),
painter: ImagePainterExtended(
imageProvider: NetworkImage('https://example.com/image.jpg'), // 替换为你的图片URL
onLoad: (imageInfo) {
// 图片加载完成后的回调,可以在这里进行额外的设置
print('Image loaded: ${imageInfo.image.width}x${imageInfo.image.height}');
},
paintImage: (Canvas canvas, Rect rect, ImageProvider image) {
// 自定义绘制逻辑
final paint = Paint()
..isAntiAlias = true
..filterQuality = FilterQuality.high;
// 绘制原始图片
canvas.drawImage(image, rect.topLeft, paint);
// 示例:在图片上绘制一个半透明矩形覆盖层
final rectPaint = Paint()
..color = Color(0x55000000) // 半透明黑色
..style = PaintingStyle.fill;
canvas.drawRect(rect, rectPaint);
// 示例:在图片上绘制文本
final textPainter = TextPainter(
text: TextSpan(
text: 'Hello Flutter!',
style: TextStyle(color: Colors.white, fontSize: 24),
),
textAlign: TextAlign.center,
textDirection: TextDirection.ltr,
)..layout(minWidth: 0, maxWidth: double.infinity);
final textPosition = rect.center - Offset(textPainter.width / 2, textPainter.height / 2);
textPainter.paint(canvas, textPosition);
},
),
),
),
);
}
}
在这个示例中,我们做了以下几件事:
- 引入必要的包:我们导入了
flutter/material.dart
和image_painter_extended
包。 - 定义
MyApp
组件:这是我们的主应用组件,其中包含一个Scaffold
,并在其body
中使用CustomPaint
组件。 - 使用
ImagePainterExtended
:在CustomPaint
的painter
属性中,我们实例化了ImagePainterExtended
,并提供了图片的网络地址。 - 自定义绘制逻辑:在
paintImage
回调中,我们首先绘制了原始图片,然后在图片上添加了一个半透明的矩形覆盖层,并绘制了文本“Hello Flutter!”。
这个示例展示了如何使用image_painter_extended
进行基本的图像绘制和自定义操作。你可以根据需要进一步扩展和修改这个示例,以实现更复杂的图像绘制效果。