Flutter文件上传与处理插件transloadit的使用
Flutter文件上传与处理插件transloadit的使用
简介
transloadit
是一个用于处理文件上传和编码的服务。它可以用来调整图片大小、裁剪、添加水印、制作GIF、转码视频、提取缩略图、生成音频波形等。简单来说,transloadit
就是处理文件的瑞士军刀。
这是一个 Flutter
SDK,用于方便地与 transloadit
的 REST API 进行通信。
安装
在 pubspec.yaml
文件中添加依赖:
dependencies:
transloadit: ^最新版本号
然后运行以下命令安装依赖:
flutter pub get
使用方法
1. 创建一个Transloadit客户端
首先,你需要创建一个 Transloadit
客户端,并使用你的认证凭证。这将允许我们向 Transloadit API
发送请求。
TransloaditClient client = TransloaditClient(
authKey: 'YOUR_AUTH_KEY',
authSecret: 'YOUR_AUTH_SECRET');
2. 调整图片大小
这个例子展示了如何使用 transloadit
API 调整图片大小。
TransloaditClient client = TransloaditClient(
authKey: 'YOUR_AUTH_KEY',
authSecret: 'YOUR_AUTH_SECRET');
// 首先我们创建一个新的Assembly
TransloaditAssembly assembly = client.newAssembly();
// 接下来我们添加两个步骤,一个是导入文件,另一个是调整图片高度为400像素
assembly.addStep("import", "/http/import", {"url": "https://demos.transloadit.com/inputs/chameleon.jpg"});
assembly.addStep("resize", "/image/resize", {"height": 400});
// 然后我们将这个Assembly发送到Transloadit进行处理
TransloaditResponse response = await assembly.createAssembly();
print(response['ok']); // 输出 "ASSEMBLY_COMPLETED"
3. 使用Assembly上传文件
用户设备上的文件可以使用 addFile
方法包含在Assembly中。
TransloaditClient client = TransloaditClient(
authKey: 'YOUR_AUTH_KEY',
authSecret: 'YOUR_AUTH_SECRET');
// 首先我们创建一个新的Assembly
TransloaditAssembly assembly = client.newAssembly();
// 添加本地文件并将其通过Tus协议随Assembly一起发送
assembly.addFile(file: file!);
assembly.addStep("resize", "/image/resize", {"height": 400});
// 然后我们将这个Assembly发送到Transloadit进行处理
TransloaditResponse response = await assembly.createAssembly();
print(response['ok']); // 输出 "ASSEMBLY_COMPLETED"
4. 使用模板和字段
你可以使用模板ID来创建一个Assembly,并传递参数。
TransloaditClient client = TransloaditClient(
authKey: 'YOUR_AUTH_KEY',
authSecret: 'YOUR_AUTH_SECRET');
// 使用模板ID创建一个Assembly
TransloaditAssembly assembly = client.runTemplate(
templateID: 'TEMPLATE_ID',
params: {'fields': {'input': 'items.jpg'}});
// 然后我们将这个Assembly发送到Transloadit进行处理
TransloaditResponse response = await assembly.createAssembly();
print(response.data["ok"]); // 输出 "ASSEMBLY_COMPLETED"
5. 跟踪上传进度
这两个回调方法跟踪的是Tus上传的进度,而不是Transloadit Assembly的进度。
TransloaditResponse response = await assembly.createAssembly(
onProgress: (progressValue) {
print(progressValue); // 浮点数从0到100
},
onComplete: () {
// 完成时执行的操作
},
);
示例代码
下面是一个完整的示例应用,演示了如何使用 transloadit
插件上传和处理文件。
import 'package:universal_io/io.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:transloadit/transloadit.dart';
void main() {
runApp(MyApp());
}
Map<int, Color> dark = {
50: Color.fromRGBO(17, 30, 50, .1),
100: Color.fromRGBO(17, 30, 50, .2),
200: Color.fromRGBO(17, 30, 50, .3),
300: Color.fromRGBO(17, 30, 50, .4),
400: Color.fromRGBO(17, 30, 50, .5),
500: Color.fromRGBO(17, 30, 50, .6),
600: Color.fromRGBO(17, 30, 50, .7),
700: Color.fromRGBO(17, 30, 50, .8),
800: Color.fromRGBO(17, 30, 50, .9),
900: Color.fromRGBO(17, 30, 50, 1),
};
Map<int, Color> light = {
50: Color.fromRGBO(0, 120, 209, .1),
100: Color.fromRGBO(0, 120, 209, .2),
200: Color.fromRGBO(0, 120, 209, .3),
300: Color.fromRGBO(0, 120, 209, .4),
400: Color.fromRGBO(0, 120, 209, .5),
500: Color.fromRGBO(0, 120, 209, .6),
600: Color.fromRGBO(0, 120, 209, .7),
700: Color.fromRGBO(0, 120, 209, .8),
800: Color.fromRGBO(0, 120, 209, .9),
900: Color.fromRGBO(0, 120, 209, 1),
};
MaterialColor transloaditDark = MaterialColor(0xFF111E32, dark);
MaterialColor transloaditLight = MaterialColor(0xFF0078D1, light);
ColorScheme colorScheme = ColorScheme(
primary: transloaditDark,
primaryVariant: dark[500]!,
secondary: transloaditLight,
secondaryVariant: light[200]!,
surface: Colors.white,
background: Colors.white,
error: Colors.redAccent,
onPrimary: Colors.white,
onSecondary: Colors.white,
onSurface: transloaditDark,
onBackground: transloaditDark,
onError: Colors.white,
brightness: Brightness.light);
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Transloadit Demo',
theme: ThemeData(
// 定义默认亮度和颜色
brightness: Brightness.light,
colorScheme: colorScheme,
sliderTheme: SliderThemeData(
valueIndicatorColor: colorScheme.primary,
activeTrackColor: colorScheme.primary,
activeTickMarkColor: colorScheme.primary,
thumbColor: colorScheme.primary,
inactiveTrackColor: colorScheme.secondaryVariant,
inactiveTickMarkColor: Colors.transparent,
valueIndicatorShape: PaddleSliderValueIndicatorShape(),
)),
home: MyHomePage(title: 'Transloadit Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
File? image;
String? imageURL;
double imageRotation = 0;
bool imageZoom = false;
bool isProcessing = false;
bool uploadComplete = false;
double progress = 0;
// 打开文件选择器以选择设备上的文件
Future<void> _pickFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'png'],
);
if (result != null) {
File file = File(result.files.single.path!);
setState(() {
image = file;
});
} else {
// 用户取消了选择
}
}
// 创建一个Transloadit Assembly来旋转用户指定数量的图像
Future<void> _processImage() async {
if (image != null) {
setState(() {
isProcessing = true;
});
TransloaditClient client = TransloaditClient(
authKey: 'YOUR_AUTH_KEY',
authSecret: 'YOUR_AUTH_SECRET');
TransloaditAssembly assembly = client.newAssembly();
assembly.addFile(file: image!);
assembly.addStep("resize", "/image/resize", {
"rotation": imageRotation,
"zoom": imageZoom,
"trim_whitespace": true,
"transparent": "#FFFFFF",
"format": "png"
});
TransloaditResponse response = await assembly.createAssembly(
onProgress: (progressValue) {
print(progressValue);
setState(() {
progress = progressValue;
});
},
onComplete: () => setState(() => uploadComplete = true),
);
setState(() {
imageURL = response.data['results']['resize'][0]['ssl_url'];
isProcessing = false;
});
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
_pickFile();
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 8.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
height: 60,
),
IconButton(
icon: Icon(
Icons.send,
color: Colors.white,
),
onPressed: () {
setState(() {
_processImage();
progress = 0;
uploadComplete = false;
});
},
),
],
),
color: transloaditDark,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TransloaditImage(
isProcessing: isProcessing,
uploadComplete: uploadComplete,
progress: progress,
imageURL: imageURL,
image: image),
Expanded(
child: Column(
children: [
TransloaditToggle(
text: 'Zoom',
value: imageZoom,
onChanged: (value) {
setState(() {
imageZoom = value;
});
},
),
Divider(),
TransloaditSlider(
text: 'Rotation',
value: imageRotation,
max: 360,
divisions: 12,
onChanged: (value) {
setState(() {
imageRotation = value;
});
}),
Divider(),
],
),
),
],
),
);
}
}
class TransloaditSlider extends StatelessWidget {
const TransloaditSlider({
Key? key,
required this.text,
required this.value,
required this.max,
required this.divisions,
required this.onChanged,
}) : super(key: key);
final String text;
final double value;
final double max;
final int divisions;
final Function(double p1) onChanged;
[@override](/user/override)
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(30, 8, 15, 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
text,
textScaleFactor: 1.5,
),
Slider(
value: value,
min: 0,
max: max,
label: value.ceil().toString(),
divisions: divisions,
onChanged: onChanged),
],
),
);
}
}
class TransloaditToggle extends StatelessWidget {
const TransloaditToggle({
Key? key,
required this.text,
required this.value,
required this.onChanged,
}) : super(key: key);
final String text;
final bool value;
final Function(bool) onChanged;
[@override](/user/override)
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(30, 8, 15, 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
text,
textScaleFactor: 1.5,
),
Switch(
value: value,
activeColor: transloaditDark,
activeTrackColor: transloaditLight[200],
inactiveThumbColor: transloaditDark,
inactiveTrackColor: transloaditDark[100],
onChanged: onChanged),
],
),
);
}
}
class TransloaditImage extends StatelessWidget {
const TransloaditImage({
Key? key,
required this.isProcessing,
required this.uploadComplete,
required this.progress,
required this.imageURL,
required this.image,
}) : super(key: key);
final bool isProcessing;
final bool uploadComplete;
final double progress;
final String? imageURL;
final File? image;
[@override](/user/override)
Widget build(BuildContext context) {
return Expanded(
child: Stack(
alignment: Alignment.center,
children: [
Container(color: Colors.grey[200]),
isProcessing
? uploadComplete
? CircularProgressIndicator()
: Align(
alignment: Alignment.bottomCenter,
child: LinearProgressIndicator(
color: transloaditDark,
backgroundColor: transloaditLight[200],
value: progress / 100,
),
)
: imageURL != null
? Image.network(imageURL!)
: image != null
? Image.file(image!)
: Image(
image: AssetImage('assets/transloadit.png'),
),
],
),
);
}
}
更多关于Flutter文件上传与处理插件transloadit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter文件上传与处理插件transloadit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用transloadit
插件进行文件上传与处理的示例代码。这个示例假定你已经设置好了Flutter开发环境,并且已经创建了一个新的Flutter项目。
首先,你需要在pubspec.yaml
文件中添加transloadit
依赖:
dependencies:
flutter:
sdk: flutter
transloadit: ^最新版本号 # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,我们编写一个Flutter页面,用于选择文件并上传到Transloadit进行处理。
import 'package:flutter/material.dart';
import 'package:transloadit/transloadit.dart';
import 'dart:io';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FileUploadPage(),
);
}
}
class FileUploadPage extends StatefulWidget {
@override
_FileUploadPageState createState() => _FileUploadPageState();
}
class _FileUploadPageState extends State<FileUploadPage> {
File? _selectedFile;
final Transloadit _transloadit = Transloadit(
authKey: '你的AuthKey', // 请替换为你的Transloadit Auth Key
authSecret: '你的AuthSecret', // 请替换为你的Transloadit Auth Secret
);
Future<void> _pickFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.any,
);
if (result != null) {
if (result.files.isNotEmpty) {
File file = File(result.files.first.path!);
setState(() {
_selectedFile = file;
});
}
}
}
Future<void> _uploadFile() async {
if (_selectedFile == null) {
return;
}
final params = {
'steps': {
'encode': {
'robot': '/video/encode',
'preset': 'h264mp4',
},
},
};
try {
final response = await _transloadit.upload(
file: _selectedFile!,
params: jsonEncode(params),
);
print('Upload successful: ${response.body}');
} catch (e) {
print('Upload failed: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('File Upload with Transloadit'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _pickFile,
child: Text('Pick a File'),
),
SizedBox(height: 20),
if (_selectedFile != null)
ElevatedButton(
onPressed: _uploadFile,
child: Text('Upload File'),
),
if (_selectedFile != null)
SizedBox(height: 20),
if (_selectedFile != null)
Text('Selected File: ${_selectedFile!.path}'),
],
),
),
);
}
}
注意事项:
-
依赖导入:确保你已经正确导入了
transloadit
包以及其他必要的包,如file_picker
(用于文件选择)。你可能需要在pubspec.yaml
中添加file_picker
依赖:dependencies: file_picker: ^最新版本号 # 请替换为实际的最新版本号
-
权限:在Android和iOS上,你可能需要添加相应的权限来访问文件系统。对于Android,这通常涉及在
AndroidManifest.xml
中添加权限声明;对于iOS,则需要在Info.plist
中添加相应的权限描述。 -
Transloadit凭证:确保你使用的是有效的Transloadit
authKey
和authSecret
。这些凭证可以从Transloadit的仪表板中获取。 -
错误处理:在实际应用中,你应该添加更多的错误处理逻辑,以确保用户体验的流畅性和可靠性。
这个示例提供了一个基本的框架,展示了如何在Flutter中使用transloadit
插件进行文件上传和处理。根据你的具体需求,你可能需要调整代码中的参数和逻辑。