How to upload an image from assets folder to server in flutter? - flutter

I need to let user pick an image from assets/images directory, I did it.
now i need to upload image selected to backend guy, i used this snap of code to convert asset path to file :
Future<File> getImageFileFromAssets(String path) async {
final byteData = await rootBundle.load('$path');
final file = File('${(await getTemporaryDirectory()).path}/$path');
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
I test the file in this line
final file = File('${(await getTemporaryDirectory()).path}/$path');
and got this as file path:
'/data/user/0/com.mohra.app/cache/assets/images/svg/dream_icons/dream-icon-9.png'
but error i got in this line :
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
the error is :
Unhandled Exception: FileSystemException: Cannot open file, path = '/data/user/0/com.mohra.app/cache/assets/images/svg/dream_icons/dream-icon-9.png' (OS Error: No such file or directory, errno = 2)
any one can help how to create file from assets path ??

Related

Flutter Image form Image Picker to Document Path

I am creating an app that saves images locally through sqflite, I have soon found out that the images are being saved as temp which means that it will be deleted by the device and i'm not able to retrieve those images anymore. I have been coding to save it to the document directory of the app but it seems to fail and throw error
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: FileSystemException: Cannot copy file to '/data/user/0/com.example.e4psmap/cache/scaled_0d5d5070-70da-4f42-9055-c31a6ed8d3d51761448072222030817.jpg', path = '/data/user/0/com.example.e4psmap/app_flutter/scaled_0d5d5070-70da-4f42-9055-c31a6ed8d3d51761448072222030817.jpg' (OS Error: No such file or directory, errno = 2)
this is my code:
void getpic(ImageSource src) async{
Uint8List byte;
final picfile = await _imagepicker.getImage(
source: src, imageQuality: 25
);
if(picfile != null){
Directory appDir = await getApplicationDocumentsDirectory();
String appdoc = appDir.path;
final filename = path.basename(picfile.path);
final local = File('${appdoc}/$filename');
final lclfile = await local.copy(picfile.path);
}
// converted = picfile!.path;
// setState(() {
// _imgfile = picfile!;
// });
Navigator.pop(context);
}
Anyone knows why I am having this errors, and any fix for this error, Thank you
The copy() function expects the source file to be passed as an argument, but in your code, you're passing picfile.path instead of the File object.
try to replace local.copy(picfile.path) with picfile.saveTo(local.path), which should save the image to the desired directory.
If you replace final with the corresponding class, the error will be very obvious.

In file picker in flutter, path was not unique

I'm trying with two different images with same name. But the path was same for two picked images. it was not unique.So that I uploaded in server second image with the same name of first uploaded image. But server had both the image are same and it had first image. So how to handle this case and customize the path?
You can use the path_provider to define the customize directory on your app.
So, copy the file with your customize path and rename the file name.
BTW, do NOT save the absolute path of File on iOS.
The iOS use SandBox to access the file. When you get the file path every time. The file path will be different.
class FileUtils {
final String avatarPath = '/avatar/';
Future<String> getAvatarDirectoryPath() async {
final String appDirPath = await getApplicationSupportDirectory().path;
final Directory avatarDirPath = await Directory(appDirPath + avatarPath).create();
return directory.path;
}
}
// Example
{
final XFile? image = await ImagePicker().pickImage(source: ImageSource.camera);
final File imageFile = File(image.path);
final File newFile = File(await FileUtils().getAvatarDirectoryPath() + 'userAvatar.png');
await imageFile.copy(newFile.path);
}

How to save File in Downloads folder in flutter?

In my flutter application I can create a pdf file, then I want to save it in Download folder.
I'm trying to achieve this goal with path_provider package, but I can't.
This is the sample code from flutter's cookbook, If I use it I don't get any error, but I don't find the file either.
final directory = await getApplicationDocumentsDirectory();
File file2 = File("${directory.path}/test.txt");
await file2.writeAsString('TEST ONE');
What's the correct way to do it?
To find the correct path please use ext_storage.
You will need this permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
on Android 10 you need this in your manifest
<application
android:requestLegacyExternalStorage="true"
on Android 11 use this instead
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
Remember to ask for them using permission_handler
I leave you my code:
static Future saveInStorage(
String fileName, File file, String extension) async {
await _checkPermission();
String _localPath = (await ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOWNLOADS))!;
String filePath =
_localPath + "/" + fileName.trim() + "_" + Uuid().v4() + extension;
File fileDef = File(filePath);
await fileDef.create(recursive: true);
Uint8List bytes = await file.readAsBytes();
await fileDef.writeAsBytes(bytes);
}
Android 11 changed a lot of things with its emphasis on scoped storage. Although /storage/emulated/0/Android/data/com.my.app/files is one of the directory paths given by the path_provider pkg, you won't be able to see files saved in /storage/emulated/0/Android/data/com.my.app/files just using any run-of-the-mill file application (Google Files, Samsung My Files, etc.).
A way to get around this (although it only works on Android) is to specify the "general" downloads folder as shown below.
Directory generalDownloadDir = Directory('/storage/emulated/0/Download');
if you write whatever file you are trying to save to that directory, it will show up in the Downloads folder in any standard file manager application, rather than just the application-specific directory that the path_provider pkg provides.
Below is some test code from an app I'm building where I save a user-generated QR code to the user's device. Just for more clarity.
//this code "wraps" the qr widget into an image format
RenderRepaintBoundary boundary = key.currentContext!
.findRenderObject() as RenderRepaintBoundary;
//captures qr image
var image = await boundary.toImage();
String qrName = qrTextController.text;
ByteData? byteData =
await image.toByteData(format: ImageByteFormat.png);
Uint8List pngBytes = byteData!.buffer.asUint8List();
//general downloads folder (accessible by files app) ANDROID ONLY
Directory generalDownloadDir = Directory('/storage/emulated/0/Download'); //! THIS WORKS for android only !!!!!!
//qr image file saved to general downloads folder
File qrJpg = await File('${generalDownloadDir.path}/$qrName.jpg').create();
await qrJpg.writeAsBytes(pngBytes);
Fluttertoast.showToast(msg: ' $qrName QR code was downloaded to ' + generalDownloadDir.path.toString(), gravity: ToastGravity.TOP);
You want getExternalStorageDirectories. You can pass a parameter to specify the downloads specifically:
final directory = (await getExternalStorageDirectories(type: StorageDirectory.downloads)).first!;
File file2 = File("${directory.path}/test.txt");
await file2.writeAsString('TEST ONE');
If you're using null safety you don't need the bang operator:
final directory = (await getExternalStorageDirectories(type: StorageDirectory.downloads)).first;
File file2 = File("${directory.path}/test.txt");
await file2.writeAsString('TEST ONE');
For downloading file in Downloads folder, here are examples:
// Save multiple files
DocumentFileSave.saveMultipleFiles([textBytes, textBytes2], ["text1.txt", "text2.txt"], ["text/plain", "text/plain"]);
//Save single text file
DocumentFileSave.saveFile(textBytes, "my_sample_file.txt", "text/plain");
//Save single pdf file
DocumentFileSave.saveFile(pdfBytes, "my_sample_file.pdf", "appliation/pdf");
//Save single image file
DocumentFileSave.saveFile(imageJPGBytes, "my_sample_file.jpg", "image/jpeg");
More details of library here:
https://pub.dev/packages/document_file_save_plus

Flutter: How to read data from video using ffmpeg

I am trying to fetch the metadata from the video for that using lib https://pub.dev/packages/flutter_ffmpeg,
Below code is not working with ffmpeg
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
File file = File('{$appDocPath}/folder_name/out.mp4');
final FlutterFFprobe _flutterFFprobe = new FlutterFFprobe();
_flutterFFprobe.getMediaInformation(file.path).then((info) => print(info));
How could I resolve the above one?
File required storage access first and then given path is accessible to ffmpeg lib
Add Storage Permission
permission_handler: ^5.0.1 // in pubspec.yaml file
Ask for runtime permission before accessing video
var status = await Permission.storage.status;
if (status.isUndetermined) {
// You can request multiple permissions at once.
Map<Permission, PermissionStatus> statuses = await [
Permission.storage,
].request();
print(statuses[Permission.storage]); // this must show permission granted.
}
Finally, use it with ffmpeg with storage path like
File file = File('/storage/emulated/0/folder_name/out.mp4');
final FlutterFFprobe _flutterFFprobe = new FlutterFFprobe();
_flutterFFprobe
.getMediaInformation(file.path)
.then((info) => print(info)); // This should print metadata inside of video

Load .pdf file / custom file from flutter assets

My question is if there is a way to load a .pdf file in app resources like assets when deploying flutter app ? I'd like to display a PDF file using this:
https://pub.dartlang.org/packages/flutter_full_pdf_viewer
but without loading from internet ;)
Copy the asset to a temporary file.
Future<File> copyAsset() async {
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
File tempFile = File('$tempPath/copy.pdf');
ByteData bd = await rootBundle.load('assets/asset.pdf');
await tempFile.writeAsBytes(bd.buffer.asUint8List(), flush: true);
return tempFile;
}