如何选择文件和图像以使用 flutter web 上传
How to Pick files and Images for upload with flutter web
我想知道如何从用户计算机中选择一张图片到我的 flutter web 应用程序中进行上传
我尝试了下面的代码并且有效。
第一个import 'dart:html';
// variable to hold image to be displayed
Uint8List uploadedImage;
//method to load image and update `uploadedImage`
_startFilePicker() async {
InputElement uploadInput = FileUploadInputElement();
uploadInput.click();
uploadInput.onChange.listen((e) {
// read file content as dataURL
final files = uploadInput.files;
if (files.length == 1) {
final file = files[0];
FileReader reader = FileReader();
reader.onLoadEnd.listen((e) {
setState(() {
uploadedImage = reader.result;
});
});
reader.onError.listen((fileEvent) {
setState(() {
option1Text = "Some Error occured while reading the file";
});
});
reader.readAsArrayBuffer(file);
}
});
}
现在只需任何小部件,如按钮并调用方法 _startFilePicker()
我测试了这个包,对结果非常满意 imagePickerWeb 它 returns 3 种不同的类型,可以是图像(用于预览的小部件)、字节、文件(上传)
然后你可以使用它来获取值
html.File _cloudFile;
var _fileBytes;
Image _imageWidget;
Future<void> getMultipleImageInfos() async {
var mediaData = await ImagePickerWeb.getImageInfo;
String mimeType = mime(Path.basename(mediaData.fileName));
html.File mediaFile =
new html.File(mediaData.data, mediaData.fileName, {'type': mimeType});
if (mediaFile != null) {
setState(() {
_cloudFile = mediaFile;
_fileBytes = mediaData.data;
_imageWidget = Image.memory(mediaData.data);
});
}
正在上传到 firebase
don't forget to add this to your index.html
<script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-storage.js"></script>
正在上传到 firebase
import 'package:firebase/firebase.dart' as fb;
uploadToFirebase(File file) async {
final filePath = 'temp/${DateTime.now()}.png';//path to save Storage
try {
fb
.storage()
.refFromURL('urlFromStorage')
.child(filePath)
.put(file);
} catch (e) {
print('error:$e');
}
}
如果还有问题,请查看包的文档
不建议直接在 Flutter 中使用 dart:html
包。
改为使用此包:https://pub.dev/packages/file_picker。
Flutter Web 中的使用示例:
class FileUploadButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
child: Text('UPLOAD FILE'),
onPressed: () async {
var picked = await FilePicker.platform.pickFiles();
if (picked != null) {
print(picked.files.first.name);
}
},
);
}
}
请注意,Flutter Web 不支持 FilePickerResult.path
。
import 'package:http/http.dart' as http;
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
class FileUploadWithHttp extends StatefulWidget {
@override
_FileUploadWithHttpState createState() => _FileUploadWithHttpState();
}
class _FileUploadWithHttpState extends State<FileUploadWithHttp> {
PlatformFile objFile = null;
void chooseFileUsingFilePicker() async {
//-----pick file by file picker,
var result = await FilePicker.platform.pickFiles(
withReadStream:
true, // this will return PlatformFile object with read stream
);
if (result != null) {
setState(() {
objFile = result.files.single;
});
}
}
void uploadSelectedFile() async {
//---Create http package multipart request object
final request = http.MultipartRequest(
"POST",
Uri.parse("Your API URL"),
);
//-----add other fields if needed
request.fields["id"] = "abc";
//-----add selected file with request
request.files.add(new http.MultipartFile(
"Your parameter name on server side", objFile.readStream, objFile.size,
filename: objFile.name));
//-------Send request
var resp = await request.send();
//------Read response
String result = await resp.stream.bytesToString();
//-------Your response
print(result);
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
//------Button to choose file using file picker plugin
RaisedButton(
child: Text("Choose File"),
onPressed: () => chooseFileUsingFilePicker()),
//------Show file name when file is selected
if (objFile != null) Text("File name : ${objFile.name}"),
//------Show file size when file is selected
if (objFile != null) Text("File size : ${objFile.size} bytes"),
//------Show upload utton when file is selected
RaisedButton(
child: Text("Upload"), onPressed: () => uploadSelectedFile()),
],
),
);
}
}
接受的答案确实过时了。就像 jnt 建议的那样,https://pub.dev/packages/file_picker 是一个方便的包,当涉及到使用 Flutter Web 实现图像上传时。
我面临的问题是获取图像的 base64 表示,因为我使用它在 Firestore 中存储图像.正如我们所知,Flutter Web 不支持 dart:io
并抛出 Unsupported operation: _Namespace
错误。因此,使用 File
和读取文件的字节不是一个选项。幸运的是,该软件包提供了 API 将上传的图像转换为 Uint8List
。这是我的实现:
import 'package:file_picker/file_picker.dart';
...
FilePickerResult? pickedFile;
...
void chooseImage() async {
pickedFile = await FilePicker.platform.pickFiles();
if (pickedFile != null) {
try {
setState(() {
logoBase64 = pickedFile!.files.first.bytes;
});
} catch (err) {
print(err);
}
} else {
print('No Image Selected');
}
}
如果您需要立即显示本地图像,请使用Image.memory
。
Image.memory(logoBase64!);
我也有这个问题;
我使用 https://pub.dev/packages/file_picker 但在 flutter web 路径中不支持;
你应该使用字节;
我将文件字节保存在 var _fileBytes 中并在请求中使用;
var request = http.MultipartRequest('POST', Uri.parse('https://.....com'));
request.headers.addAll(headers);
request.files.add(
http.MultipartFile.fromBytes(
'image',
await ConvertFileToCast(_fileBytes),
filename: fileName,
contentType: MediaType('*', '*')
)
);
request.fields.addAll(fields);
var response = await request.send();
函数 ConvertFileToCast:
ConvertFileToCast(data){
List<int> list = data.cast();
return list;
}
对我有用:)
如果有人想知道如何让它在移动和网络上运行:
var bytes;
await file!.files.first.readStream!
.map((asciiValue) => bytes = asciiValue)
.toList();
FormData body;
final MultipartFile file = MultipartFile.fromBytes(bytes, filename: "file");
MapEntry<String, MultipartFile> imageEntry = MapEntry("image", file);
body.files.add(imageEntry);
我想知道如何从用户计算机中选择一张图片到我的 flutter web 应用程序中进行上传
我尝试了下面的代码并且有效。
第一个import 'dart:html';
// variable to hold image to be displayed
Uint8List uploadedImage;
//method to load image and update `uploadedImage`
_startFilePicker() async {
InputElement uploadInput = FileUploadInputElement();
uploadInput.click();
uploadInput.onChange.listen((e) {
// read file content as dataURL
final files = uploadInput.files;
if (files.length == 1) {
final file = files[0];
FileReader reader = FileReader();
reader.onLoadEnd.listen((e) {
setState(() {
uploadedImage = reader.result;
});
});
reader.onError.listen((fileEvent) {
setState(() {
option1Text = "Some Error occured while reading the file";
});
});
reader.readAsArrayBuffer(file);
}
});
}
现在只需任何小部件,如按钮并调用方法 _startFilePicker()
我测试了这个包,对结果非常满意 imagePickerWeb 它 returns 3 种不同的类型,可以是图像(用于预览的小部件)、字节、文件(上传)
然后你可以使用它来获取值
html.File _cloudFile;
var _fileBytes;
Image _imageWidget;
Future<void> getMultipleImageInfos() async {
var mediaData = await ImagePickerWeb.getImageInfo;
String mimeType = mime(Path.basename(mediaData.fileName));
html.File mediaFile =
new html.File(mediaData.data, mediaData.fileName, {'type': mimeType});
if (mediaFile != null) {
setState(() {
_cloudFile = mediaFile;
_fileBytes = mediaData.data;
_imageWidget = Image.memory(mediaData.data);
});
}
正在上传到 firebase
don't forget to add this to your index.html
<script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-storage.js"></script>
正在上传到 firebase
import 'package:firebase/firebase.dart' as fb;
uploadToFirebase(File file) async {
final filePath = 'temp/${DateTime.now()}.png';//path to save Storage
try {
fb
.storage()
.refFromURL('urlFromStorage')
.child(filePath)
.put(file);
} catch (e) {
print('error:$e');
}
}
如果还有问题,请查看包的文档
不建议直接在 Flutter 中使用 dart:html
包。
改为使用此包:https://pub.dev/packages/file_picker。
Flutter Web 中的使用示例:
class FileUploadButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
child: Text('UPLOAD FILE'),
onPressed: () async {
var picked = await FilePicker.platform.pickFiles();
if (picked != null) {
print(picked.files.first.name);
}
},
);
}
}
请注意,Flutter Web 不支持 FilePickerResult.path
。
import 'package:http/http.dart' as http;
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
class FileUploadWithHttp extends StatefulWidget {
@override
_FileUploadWithHttpState createState() => _FileUploadWithHttpState();
}
class _FileUploadWithHttpState extends State<FileUploadWithHttp> {
PlatformFile objFile = null;
void chooseFileUsingFilePicker() async {
//-----pick file by file picker,
var result = await FilePicker.platform.pickFiles(
withReadStream:
true, // this will return PlatformFile object with read stream
);
if (result != null) {
setState(() {
objFile = result.files.single;
});
}
}
void uploadSelectedFile() async {
//---Create http package multipart request object
final request = http.MultipartRequest(
"POST",
Uri.parse("Your API URL"),
);
//-----add other fields if needed
request.fields["id"] = "abc";
//-----add selected file with request
request.files.add(new http.MultipartFile(
"Your parameter name on server side", objFile.readStream, objFile.size,
filename: objFile.name));
//-------Send request
var resp = await request.send();
//------Read response
String result = await resp.stream.bytesToString();
//-------Your response
print(result);
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
//------Button to choose file using file picker plugin
RaisedButton(
child: Text("Choose File"),
onPressed: () => chooseFileUsingFilePicker()),
//------Show file name when file is selected
if (objFile != null) Text("File name : ${objFile.name}"),
//------Show file size when file is selected
if (objFile != null) Text("File size : ${objFile.size} bytes"),
//------Show upload utton when file is selected
RaisedButton(
child: Text("Upload"), onPressed: () => uploadSelectedFile()),
],
),
);
}
}
接受的答案确实过时了。就像 jnt 建议的那样,https://pub.dev/packages/file_picker 是一个方便的包,当涉及到使用 Flutter Web 实现图像上传时。
我面临的问题是获取图像的 base64 表示,因为我使用它在 Firestore 中存储图像.正如我们所知,Flutter Web 不支持 dart:io
并抛出 Unsupported operation: _Namespace
错误。因此,使用 File
和读取文件的字节不是一个选项。幸运的是,该软件包提供了 API 将上传的图像转换为 Uint8List
。这是我的实现:
import 'package:file_picker/file_picker.dart';
...
FilePickerResult? pickedFile;
...
void chooseImage() async {
pickedFile = await FilePicker.platform.pickFiles();
if (pickedFile != null) {
try {
setState(() {
logoBase64 = pickedFile!.files.first.bytes;
});
} catch (err) {
print(err);
}
} else {
print('No Image Selected');
}
}
如果您需要立即显示本地图像,请使用Image.memory
。
Image.memory(logoBase64!);
我也有这个问题;
我使用 https://pub.dev/packages/file_picker 但在 flutter web 路径中不支持;
你应该使用字节;
我将文件字节保存在 var _fileBytes 中并在请求中使用;
var request = http.MultipartRequest('POST', Uri.parse('https://.....com'));
request.headers.addAll(headers);
request.files.add(
http.MultipartFile.fromBytes(
'image',
await ConvertFileToCast(_fileBytes),
filename: fileName,
contentType: MediaType('*', '*')
)
);
request.fields.addAll(fields);
var response = await request.send();
函数 ConvertFileToCast:
ConvertFileToCast(data){
List<int> list = data.cast();
return list;
}
对我有用:)
如果有人想知道如何让它在移动和网络上运行:
var bytes;
await file!.files.first.readStream!
.map((asciiValue) => bytes = asciiValue)
.toList();
FormData body;
final MultipartFile file = MultipartFile.fromBytes(bytes, filename: "file");
MapEntry<String, MultipartFile> imageEntry = MapEntry("image", file);
body.files.add(imageEntry);