I am new to Flutter and coding. I followed the guide here for how to add a watermark to an image. However, I am not using image picker, but using an image stored within Firebase, and a watermark that is an asset.
The code builds fine, but when I press the button to generate the watermarked image and eventually share it, I get the following error
Unhandled Exception: FileSystemException: Cannot open file, path = 'firebase url path' (OS Error: No such file or directory, errno = 2)
It is recognizing the path to the image in Firebase, but for some reason is saying the file isn't available. The error is being thrown on the 'decodeImage' portion of the code below.
Code snippet below
import '../backend/image_share/image_share.dart';
import 'package:image/image.dart' as ui;
import 'dart:io';
onPressed: () async {
//first image is a firebase path
final pickedFile = File('firebae path');
//second image is watermark and an asset
final watermark = File('assets/images/Share-small.png');
ui.Image originalImage = ui.decodeImage(pickedFile.readAsBytesSync());
ui.Image watermarkImage = ui.decodeImage(watermark.readAsBytesSync());
ui.drawImage(originalImage, watermarkImage);
ui.drawString(originalImage, ui.arial_24, 100, 120, 'Test!');
List<int> wmImage = ui.encodePng(originalImage);
final uploadUrl = await uploadData('new firebase data', wmImage);
final 'new firebase data' = FB collection(sharedImage: uploadUrl);
I am having trouble figuring out how to read/upload the image file before manipulating them.
The File class can only read/write files that are on the local system. It does not have any knowledge of files in Cloud Storage.
You will need to:
download the file from Cloud Storage,
add the watermark on the device, and then
write the resulting file back to Cloud Storage.
Related
In my app, I am picking a photo from gallery and save it's path with ImagePicker. Then, I am showing it with the path I saved. The problem is, ImagePicker is giving me a different path every time even if I choose the same picture again so I can not open the image with the path I saved, it's giving the error no such file. How I am getting the path is:
onPressed: () async {
final XFile? image =
await imagePicker.pickImage(source: ImageSource.gallery);
if (image != null) {
setState(() {
imagePath = image.path;
});
}
},
It gives me a path like this: "/private/var/mobile/Containers/Data/Application/..." so on. How can I get the actual path and open it?
ImagePicker will create a copy of the image to your app's cache directory, thus you need to move it into a more stable location.
It also has no knowledge of what was picked before, thus it will create a new image every time you pick it. If you need to have a stable file path based on the image, perhaps give a try to file_picker.
I am trying to pick image from gallery or camera by image_picker, and save image at specific location. My code work perfectly when i pick image from camera, but it through an exception when i pick from gallery while saving. Here is my code
onPressed: () async {
final XFile? image = await picker.pickImage(source: ImageSource.gallery);
File tempFile = File(image.path);
tempFile = await tempFile.copy('storage/emulated/0/$image.name');
}
Above code through an exception
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: FileSystemException: Cannot copy file to 'storage/emulated/0//6544578463230218846.jpg', path = '/data/user/0/com.example.nysu/cache/image_picker6544578463230218846.jpg' (OS Error: No such file or directory, errno = 2)
First make sure that you have the required permissions:
For example for Android you need:
Also the file path seems a bit weird with the extra "/", you might want to fix that if it is not intentional:
'storage/emulated/0//6544578463230218846.jpg'
Like so:
tempFile = await tempFile.copy('storage/emulated/0$image.name');
Basic Flow of my application is that, firs i choose image from gallery or camera and then i input name for image from user and then i save image with user provided name to local storage.
So in between interval of choosing image and after that input name, cache memory for image picker is lost some time, because of this (OS Error: No such file or directory, errno = 2) happens.
To solve this i input name before choosing image, and instantly save image after choosing them. It works perfectly.
I am using the multiple file picker package on pub.dev, the link is below https://pub.dev/packages/multi_image_picker in conjunction with the image cropper package by Yalantis
https://pub.dev/packages/image_cropper
to let my user pick multiple images and then crop them at will.
I am using this code to convert my asset into a file and feed it into the cropper. And it works.
final temp = await Directory.systemTemp.createTemp();
final data = await finalList[index].getByteData();
File failo = await File('${temp.path}/img').writeAsBytes(
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
print("The path is ${temp.path}");
File croppedFailo = await ImageCropper.cropImage(
sourcePath: failo.path,
androidUiSettings: AndroidUiSettings(toolbarTitle: "My App"),
);
The tricky bit is to convert it back to an asset so that i can replace the old uncropped asset with this new cropped one..I read through the Asset documentation of the package and I tried this but it made my app crash
Asset croppedPic = new Asset(
croppedFailo.path,
DateTime.now().millisecondsSinceEpoch.toString(),
300,
300,
);
finalList.replaceRange(index, index + 1, [croppedPic]);
EDIT: When i say "asset", i am not referring to images i manually added to the assets/images folder in the app. The multi image picker plugin has a file- type called asset in which it returns images. That is the type to which i want to convert my file back into.
Never mind. I figured it's too unnecessarily complicated to do that. So, i instead just reformatted my entire code to handle images as files instead of assets. And, it actually made my life a lot simpler coz files give you more versatility and less problems than assets.
I'm using the flutter camera package to record videos and save videos to a temporary directory after which I use flutter's ffmpeg package to do some transformation. However, to achieved this, I first had to make a copy of the recorded video to create the output file path.
The challenge comes in when I'm trying to load the asset from the device. The block of code below does the copying and renaming of the file.
static Future<File> copyFileAssets(String assetName, String localName) async {
ByteData assetByteData = await rootBundle.load(assetName);
final List<int> byteList = assetByteData.buffer
.asUint8List(assetByteData.offsetInBytes, assetByteData.lengthInBytes);
final String fullTemporaryPath =
join((await tempDirectory).path, localName);
return new File(fullTemporaryPath)
.writeAsBytes(byteList, mode: FileMode.writeOnly, flush: true);
}
The issue lies with this line ByteData assetByteData = await rootBundle.load(assetName);
I get this error message Unable to load asset: /storage/emulated/0/Android/data/com.timz/files/timz/1585820950555.mp4, but the weird thing is, this only happens when I run the build for the first. Everything else works fine on subsequent hot restarts.
I later got this fix by myself rootBundle is meant for loading only assets you've declared their paths on your pubspec.yaml but somehow, it miraculously loads the saved file when hot restart was applied.
Reading the file as bytes gave what I wanted as load it with root bundle. Here's the code below.
Uint8List assetByteData = await File(assetName).readAsBytes();
The goal is to:
1) Allow the user to choose a picture [I use image_picker for that]
2) User crops image to a 1:1 aspect ratio [I use image_crop for that]
3) Upload image to Python backend
The problem:
After cropping image, attempting to read the image to Post it returns:
Unhandled Exception: FileSystemException: Cannot open file, path = '/data/user/0/com.example.AppName/cache/image_crop_26d4daef-e297-456c-9c6d-85d2e4c0d0662042323543401355956.jpg' (OS Error: No such file or directory, errno = 2)
The weird part is, I can display the image just fine within Flutter using `FileImage(_imageFile)' (considering _imageFile is the File variable)
It's just that I cannot use _imageFile.length() or even base64Encode(_imageFile.readAsBytesSync()).
Any ideas on what's happening and how to fix it?
path_provider plugin supports access to two filesystem locations:
Temporary directory,
Documents directory.
— The temporary directory is the cache and its content may be erased by the system at any time. So, storing data here is not good for us to get it later.
— The documents directory is the one we to choose now, this is a directory for the app to store files that only it can access
And You are using temporary directory (/data/user/0/com.example.AppName/cache/image_crop_26d4daef-e297-456c-9c6d-85d2e4c0d0662042323543401355956.jpg)
And if file is not erased then you can use following snippet to read file content:
final directory = await getTemporaryDirectory();
// For your reference print the AppDoc directory
final path = directory.path;
final file = File('$path/data.txt');
String contents = await file.readAsString();
return contents;