我想知道如何从用户的电脑到我的Flutter网络应用程序上传图像
tez616oj1#
不建议在Flutter中直接使用dart:html包。使用这个包:https://pub.dev/packages/file_picker。如何在Flutter Web中使用:
dart:html
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。
FilePickerResult.path
omhiaaxx2#
我尝试了下面的代码,它工作了。第一个import 'dart:html';
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); } }); }
现在只要任何Widget,比如按钮,就调用方法_startFilePicker()
_startFilePicker()
nzkunb0c3#
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()), ], ), ); } }
ebdffaop4#
我已经测试了这个包,并与结果imagePickerWeb非常高兴,它返回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别忘了把这个加到你的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'); } }
如果仍然有问题,请参阅软件包的文档
gpnt7bae5#
公认的答案确实过时了。就像jnt建议的那样,https://pub.dev/packages/file_picker是一个方便的包,当涉及到使用Flutter Web实现图像上传时。我面临的问题是获取一个 base64 表示的图像,因为我用它来存储 Firestore 中的图像。正如我们所知,Flutter Web不支持dart:io,并抛出Unsupported operation: _Namespace错误。因此,使用File并阅读文件的字节不是一个选择。幸运的是,该包提供了将上传的图像转换为Uint8List的API。下面是我的实现:
dart:io
Unsupported operation: _Namespace
File
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'); } }
如果您需要立即显示本Map像,请使用Image.memory。
Image.memory
Image.memory(logoBase64!);
vhipe2zx6#
我也有这个问题,我使用了https://pub.dev/packages/file_picker,但在 Flutter 网络路径中不支持;你应该使用字节;i将文件字节保存在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; }
这是为我工作:)
xlpyo6sf7#
更新:amplify_storage_s3从v1.0.0开始支持Flutter Web。
...我可以分享的方式我upload image to AWS s3 from flutter web最近。可能不完全符合谁在这里寻找答案的情况,但我认为它可能会以某种方式激励其他人。首先,我尝试使用amplify_storage_s3包,但它目前还不支持Flutter Web。所以我用基本的http post代替。我使用的软件包:
upload image to AWS s3 from flutter web
代码示例:
import 'package:flutter/material.dart'; import 'package:dio/dio.dart' as dio; import 'package:file_picker/file_picker.dart'; import 'package:mime/mime.dart'; class FileUploader extends StatelessWidget { const FileUploader({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton( onPressed: () async { // 1. Pick an image file final filePicked = await FilePicker.platform.pickFiles(); if (filePicked != null) { final file = filePicked.files.single; // PlatformFile final mimeType = lookupMimeType(file.name) ?? ''; /// 2. Get presigned data somewhere const url = 'https://s3.amazonaws.com/......'; final fields = { 'bucket': '...', 'X-Amz-Algorithm': 'AWS4-HMAC-SHA256', 'X-Amz-Credential': '...', 'X-Amz-Date': '...', 'Policy': '...', 'X-Amz-Signature': '...', 'x-amz-meta-userid': '...', 'Content-Type': mimeType, 'file': dio.MultipartFile.fromBytes(file.bytes ?? []), }; /// 3. Send file to AWS s3 final formData = dio.FormData.fromMap(fields); await dio.Dio().post(url, data: formData); } }, child: const Icon(Icons.upload), ), ); } }
wfveoks08#
如果有人想知道如何让它在移动的和Web上工作:
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);
nbewdwxp9#
下面是我使用dio上传的工作代码。我使用dio是因为它有一个回调进度函数。
class _FileUploadViewState extends State<FileUploadView> { @override void initState() { super.initState(); } FilePickerResult? result; PlatformFile? file; Response? response; String? progress; String? percentage; Dio dio = Dio(); selectFile() async { result = await FilePicker.platform.pickFiles(type: FileType.any, withData: true); if (result != null) { file = result?.files.single; } //print(file?.name); //print(file?.bytes?.length); //print(file?.size); //print(file?.extension); //print(file?.path); setState(() {}); } Future<void> uploadFile(BuildContext context, User user) async { final navigator = Navigator.of(context); final storage = FlutterSecureStorage(); String? token = await storage.read(key: 'jwt'); final formData = FormData.fromMap( { 'file': MultipartFile.fromBytes(file?.bytes as List<int>, filename: file?.name) }, ); dio.options.headers['content-Type'] = 'application/octet-stream'; dio.options.headers["authorization"] = "Bearer $token"; response = await dio.post( user.fileUrl, data: formData, onSendProgress: (int sent, int total) { percentage = (sent / total * 100).toStringAsFixed(2); progress = "$sent Bytes of $total Bytes - $percentage % uploaded"; setState( () {}, ); }, ); if (response!.statusCode == 200) { ....
服务器的go代码如下所示,
if err := r.ParseMultipartForm(64 << 20); err != nil { log.Println("error processing multipart form") log.Println(err) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } file, handler, err := r.FormFile("file")
9条答案
按热度按时间tez616oj1#
不建议在Flutter中直接使用
dart:html
包。使用这个包:https://pub.dev/packages/file_picker。
如何在Flutter Web中使用:
请注意,Flutter Web不支持
FilePickerResult.path
。omhiaaxx2#
我尝试了下面的代码,它工作了。
第一个
import 'dart:html';
现在只要任何Widget,比如按钮,就调用方法
_startFilePicker()
nzkunb0c3#
ebdffaop4#
我已经测试了这个包,并与结果imagePickerWeb非常高兴,它返回3种不同的类型,它可以在图像的形式(小部件预览),字节,文件(上传)
然后你可以用它来得到
上传到Firebase
别忘了把这个加到你的index.html里
上传到Firebase
如果仍然有问题,请参阅软件包的文档
gpnt7bae5#
公认的答案确实过时了。就像jnt建议的那样,https://pub.dev/packages/file_picker是一个方便的包,当涉及到使用Flutter Web实现图像上传时。
我面临的问题是获取一个 base64 表示的图像,因为我用它来存储 Firestore 中的图像。正如我们所知,Flutter Web不支持
dart:io
,并抛出Unsupported operation: _Namespace
错误。因此,使用File
并阅读文件的字节不是一个选择。幸运的是,该包提供了将上传的图像转换为Uint8List
的API。下面是我的实现:如果您需要立即显示本Map像,请使用
Image.memory
。vhipe2zx6#
我也有这个问题,
我使用了https://pub.dev/packages/file_picker,但在 Flutter 网络路径中不支持;
你应该使用字节;
i将文件字节保存在var _fileBytes中,并在请求中使用;
函数ConvertFileToCast:
这是为我工作:)
xlpyo6sf7#
更新:amplify_storage_s3从v1.0.0开始支持Flutter Web。
...
我可以分享的方式我
upload image to AWS s3 from flutter web
最近。可能不完全符合谁在这里寻找答案的情况,但我认为它可能会以某种方式激励其他人。首先,我尝试使用amplify_storage_s3包,但它目前还不支持Flutter Web。所以我用基本的http post代替。
我使用的软件包:
代码示例:
wfveoks08#
如果有人想知道如何让它在移动的和Web上工作:
nbewdwxp9#
下面是我使用dio上传的工作代码。我使用dio是因为它有一个回调进度函数。
服务器的go代码如下所示,