1

I am using the Multi_Image_Picker plugin to get multiple images. Multi_Image_Picker returns a List<Asset> files when selecting multiple images. How would I be able to use Multi_Image_Picker along with Image_Cropper which only accepts the path to the image? I couldn't get the path of the image since its an Asset type. Here is what I've tried in order to achieve it:

I could get the path of the image:

final filePath = await FlutterAbsolutePath.getAbsolutePath(assets.identifier);

This works but then flutter_absolute_path plugin requires the minimum android sdk to be 19. Is there another to crop images without converting the Asset File into an Image File?

I tried converting the Asset to Image File:

List<File> images = List<File>();
Directory tempDir = await getTemporaryDirectory();
final path =tempDir.path;
for (int i = 0; i < assets.length; i++) {
   images.add(await ProcessImage.assetToFile(
     path: "$path/images/img$i",
      data: await assets[i].getByteData(quality: 90)));
}

assetToFile():

static Future<File> assetToFile({ByteData data, String path})async {
return File(path).writeAsBytes(
      data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
}
CoderUni
  • 5,474
  • 7
  • 26
  • 58
  • connot you copy the original files to some temporary folder? – pskink Jul 24 '20 at 03:55
  • but the user has to crop each file before uploading, so whats the problem if it takes a couple of milliseconds longer? – pskink Jul 24 '20 at 04:09
  • @pskink I think you're right. I will do what you've suggested. Thank you. – CoderUni Jul 24 '20 at 04:40
  • @pskink I've tried this: https://stackoverflow.com/questions/50119676/how-to-write-a-bytedata-instance-to-a-file-in-dart but I got an error: Unhandled Exception: FileSystemException: Cannot open file, path = 'images/img0' (OS Error: No such file or directory, errno = 2) . What seems to be wrong? – CoderUni Jul 24 '20 at 06:54
  • how can i know if i dont see your code? – pskink Jul 24 '20 at 07:01
  • @pskink Sorry about that. I forgot to post my code. I updated my question. Thanks. – CoderUni Jul 24 '20 at 07:06
  • you have to create a parent folder first - in your case it seems that getTemporaryDirectory()).path/images does not exist – pskink Jul 24 '20 at 07:14
  • @pskink How would I be able to do it with await getTemporaryDirectory()? – CoderUni Jul 24 '20 at 07:15
  • of course you have to use `await`: i just used pseudo code – pskink Jul 24 '20 at 07:16
  • @pskink I don't understand what you meant. I used `File('${(await getTemporaryDirectory()).path}/$path').writeAsBytes()`. Doesn't `'${(await getTemporaryDirectory()).path}/$path'` create a folder already? – CoderUni Jul 24 '20 at 07:20
  • no it does not,. you have to create it, for example: `final directory = await Directory.systemTemp.createTemp();` – pskink Jul 24 '20 at 07:24
  • @pskink Thanks for the suggestion but it still returns the same error. I updated the code above based on what you've suggested. – CoderUni Jul 24 '20 at 07:52
  • you are not creating the folder where you want to save your files - `File(someFilePath)` does NOT create any folders – pskink Jul 24 '20 at 08:00
  • for example, what do oyu see on the logs if you run this: `var tmp = await Directory.systemTemp.createTemp(); print('temporary folder: ${tmp.path}'); ['a', 'b', 'c'].forEach((element) { var file = File('${tmp.path}/$element') ..writeAsStringSync(element * 16); print('${file.path} created'); });` ? – pskink Jul 24 '20 at 08:13
  • @pskink Thank you it worked. Sorry for asking too much, I really don't get it. Would you like to copy and paste it as your answer as the answer to this question? I will happily accept and upvote it – CoderUni Jul 24 '20 at 08:34
  • great, post a self answer then – pskink Jul 24 '20 at 08:39
  • @pskink Thanks, I wrote the answer. If you want to add more things or edit my answer, I'll edit my answer. – CoderUni Jul 24 '20 at 09:31

2 Answers2

4

Thanks to @pskink for the answer. It turns out that you have to save the obtained asset byte data to a temporary folder as a file and use it in your cropper.

final temp = await Directory.systemTemp.createTemp();
List<File> images = List<File>();
 for (int i = 0; i < assets.length; i++) {
    final data = await assets[i].getByteData();
    images.add(await File('${temp.path}/img$i').writeAsBytes(
      data.buffer.asUint8List(
        data.offsetInBytes, data.lengthInBytes)));
}
CoderUni
  • 5,474
  • 7
  • 26
  • 58
1

You can find a good example of a combination of three packages in below Github repository:

  • multi_image_picker
  • image_cropper
  • photofilters

https://github.com/flutterstudygn/multiple_image_selector

Key features

  • Pick multiple images.
  • Take a picture in the grid view.
  • Restrict the maximum count of images the user can pick.
  • Adjust cropping for each image.
  • Adjust filter for each image.