Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image picker flutter web 1.9

Looking for image picker on new flutter web 1.9. I found a way but for less than 1.9, now that is merged dont know how can i achived this. Tried with dart:html but is not working on release! Only on running

like image 232
Juan Jose Rodrigo Avatar asked Sep 21 '19 19:09

Juan Jose Rodrigo


People also ask

How do I select multiple images using image picker in flutter?

To select multiple images we will use image_picker flutter package. in this Package, we can select multiple images from the gallery.


2 Answers

It seems like as for Flutter web 1.10 dev , universal_html package is good candidate for the temporarily vacant position of dart:html:

import 'dart:convert';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:universal_html/prefer_universal/html.dart' as html;

class ImagePickerLabPage extends StatefulWidget {
  @override
  _ImagePickerLabPageState createState() => _ImagePickerLabPageState();
}

class _ImagePickerLabPageState extends State<ImagePickerLabPage> {
  String name = '';
  String error;
  Uint8List data;

  pickImage() {
    final html.InputElement input = html.document.createElement('input');
    input
      ..type = 'file'
      ..accept = 'image/*';

    input.onChange.listen((e) {
      if (input.files.isEmpty) return;
      final reader = html.FileReader();
      reader.readAsDataUrl(input.files[0]);
      reader.onError.listen((err) => setState(() {
            error = err.toString();
          }));
      reader.onLoad.first.then((res) {
        final encoded = reader.result as String;
        // remove data:image/*;base64 preambule
        final stripped =
            encoded.replaceFirst(RegExp(r'data:image/[^;]+;base64,'), '');

        setState(() {
          name = input.files[0].name;
          data = base64.decode(stripped);
          error = null;
        });
      });
    });

    input.click();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(name),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.open_in_browser),
        onPressed: () {
          pickImage();
        },
      ),
      body: Center(
        child: error != null
            ? Text(error)
            : data != null ? Image.memory(data) : Text('No data...'),
      ),
    );
  }
}
like image 189
Spatz Avatar answered Nov 14 '22 22:11

Spatz


Actually onChange doesn't work well on mobile safari, it need to change addEventListener and also need to append it.

Future<void> _setImage() async {
    final completer = Completer<List<String>>();
    InputElement uploadInput = FileUploadInputElement();
    uploadInput.multiple = true;
    uploadInput.accept = 'image/*';
    uploadInput.click();
    // onChange doesn't work on mobile safari
    uploadInput.addEventListener('change', (e) async {
        // read file content as dataURL
        final files = uploadInput.files;
        Iterable<Future<String>> resultsFutures = files.map((file) {
            final reader = FileReader();
            reader.readAsDataUrl(file);
            reader.onError.listen((error) => completer.completeError(error));
            return reader.onLoad.first.then((_) => reader.result as String);
        });

        final results = await Future.wait(resultsFutures);
        completer.complete(results);
    });
    // need to append on mobile safari
    document.body.append(uploadInput);
    final List<String> images = await completer.future;
    setState(() {
        _uploadedImages = images;
    });
    uploadInput.remove();
}

This also works:

Future<void> _setImage() async {   
    final completer = Completer<List<String>>();
    final InputElement input = document.createElement('input');
    input
      ..type = 'file'
      ..multiple = true
      ..accept = 'image/*';
    input.click();
    // onChange doesn't work on mobile safari
    input.addEventListener('change', (e) async {
      final List<File> files = input.files;
      Iterable<Future<String>> resultsFutures = files.map((file) {
        final reader = FileReader();
        reader.readAsDataUrl(file);
        reader.onError.listen((error) => completer.completeError(error));
        return reader.onLoad.first.then((_) => reader.result as String);
      });
      final results = await Future.wait(resultsFutures);
      completer.complete(results);
    });
    // need to append on mobile safari
    document.body.append(input);
    // input.click(); can be here
    final List<String> images = await completer.future;
    setState(() {
      _uploadedImages = images;
    });
    input.remove();
}
like image 27
user12208004 Avatar answered Nov 14 '22 22:11

user12208004