Select 移动设备上的 flutter web 图片

Select image for flutter web on mobile device

我目前正在使用 https://pub.dev/packages/file_picker 这个功能

FilePickerResult result =
    await FilePicker.platform.pickFiles();

if (result != null) {
  setState(() {
    filePicked = result;
  });

for (int i = 0; i < result.files.length; i++) {
    setState(() {
      listBytes.add(result.files[i].bytes);
    });
  }
} else {
  // User canceled the picker
}

当我在网络上测试时它成功运行,但是当 运行 在网络应用程序(移动设备)上 select 图像后没有响应时出现问题。很难调试,因为我真的不知道如何调试 Web 应用程序。我的问题是,我可以只使用我在 web 上使用的功能,还是我需要使用任何特定功能才能在 web 应用程序中使用。

您可以在网络应用上试试这个方法(此方法只适用于网络平台):

import '../../models/html_nonweb.dart'
    if (dart.library.js) 'dart:html' as html;

  Future<WebFileModel> pickWebFileModel() {
    final completer = Completer<WebFileModel>();
    final html.InputElement input =
        html.document.createElement('input') as html.InputElement;
    input
      ..type = 'file'
      ..accept = 'image/*';
    input.onChange.listen((e) async {
      final List<html.File> files = input.files!;
      final reader = html.FileReader();
      reader.readAsDataUrl(files.first);
      reader.onError.listen(completer.completeError);
      final Future<WebFileModel> resultsFutures =
          reader.onLoad.first.then((_) => WebFileModel(
                path: reader.result! as String,
                type: files.first.type as String,
                createdAt: DateTime.fromMillisecondsSinceEpoch(
                  files.first.lastModified!,
                ),
                htmlFile: files.first,
              ));
      final results = await resultsFutures;
      completer.complete(results);
    });
    input.click();
    return completer.future;
  }

要使用此代码,您需要创建 html_nonweb.dart 文件:

const document = Document();

class Document {
  const Document();

  Element createElement(String el) => InputElement();
}

class File {
  final int? lastModified = null;

  final String? type = null;
}

class Element {
  const Element();
}

class InputElement extends Element {
  const InputElement();

  final List<File>? files = null;

  Stream<Object> get onChange => Stream.empty();

  set type(String type) {}

  set multiple(bool multiple) {}

  set accept(String s) {}

  void readAsDataUrl(File file) {}

  void click() {}
}

class FileReader {
  Stream<void Function(Object error, [StackTrace? stackTrace])> get onError =>
      Stream.empty();

  void readAsDataUrl(File file) {}

  Stream<Object> get onLoad => Stream.empty();

  final Object? result = null;
}

和 WebFileModel:

import 'dart:typed_data';

import 'html_nonweb.dart' if (dart.library.js) 'dart:html' as html;

class WebFileModel {
  final String path;
  final String type;
  final DateTime createdAt;
  final html.File? htmlFile;
  final Uint8List? uIntFile;

  WebFileModel({
    required this.path,
    required this.type,
    required this.createdAt,
    this.htmlFile,
    this.uIntFile,
  });

  WebFileModel copyWith({
    String? path,
    String? type,
    DateTime? createdAt,
    html.File? htmlFile,
    Uint8List? uIntFile,
  }) {
    return WebFileModel(
      path: path ?? this.path,
      type: type ?? this.type,
      createdAt: createdAt ?? this.createdAt,
      htmlFile: htmlFile ?? this.htmlFile,
      uIntFile: uIntFile ?? this.uIntFile,
    );
  }
}

要获取 Uint8List,您需要执行以下操作:

final imageBase64 =media.path.replaceFirst(RegExp(r'data:image/[^;]+;base64,'), '');
final uIntFile = base64Decode(imageBase64);