I'm trying to save a ByteData image generated from canvas into the device download folder. However, I was only able to save it into my apps android/data/ directory using the code below...
Future<void> saveImage(
String fileName,
ByteData image,
) async {
final directoryName = "Generated";
Directory directory = await getExternalStorageDirectory();
String path = directory.path;
await Directory('$path/$directoryName').create(recursive: true);
File('$path/$directoryName/$fileName.png').writeAsBytesSync(image.buffer.asInt8List());
}
but, it's not convenient for the user to go into this deep directory just to get the image, so I want to save it into the Download directory but I don't know how. I have tried several approaches but I keep on receiving permission errors. Like for example using this code below (downloads_path_provider)...
Directory directory = await DownloadsPathProvider.downloadsDirectory;
String path = directory.path;
File('$path/$fileName.png').writeAsBytesSync(image.buffer.asInt8List());
PS. It would be much better if there's a way to save it somewhere that will show in the Phone's Gallery
You can save images to gallery with this package on pub.dev : 'gallery_saver' : https://pub.dev/packages/gallery_saver
Related
I want to copy an audio file to music folder in the storage. I have the path where the audio is, like '/data/user/0/app/audioFile' and I am passing to the function as 'audioPath'. I need help to finish this function, what can I do?
void _downloadAudio(audioPath) async {
var file = File(audioPath);
//get the music folder
await file.copy(music folder path);
}
You can use the getExternalStorageDirectory method from the dart:io library to get the path to the external storage directory on the device. This is where you can store files that are meant to be shared between apps or accessible to the user, such as music files. You can then use this path to construct the full path to the desired music folder. Here's an updated version of the function that will copy the audio file to the music folder:
import 'dart:io';
void _downloadAudio(String audioPath) async {
var file = File(audioPath);
// Get the external storage directory
final externalStorageDirectory = await getExternalStorageDirectory();
// Construct the full path to the music folder
final musicFolderPath = '${externalStorageDirectory.path}/Music';
// Check if the music folder exists, and create it if it doesn't
final musicFolder = Directory(musicFolderPath);
if (!await musicFolder.exists()) {
await musicFolder.create();
}
// Copy the audio file to the music folder
await file.copy('$musicFolderPath/${file.basename}');
}
Note that accessing the external storage directory requires the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions, so you'll need to request these permissions from the user if your app doesn't already have them.
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'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;