I am building an app in flutter and I want to store many images. So will anyone suggest me where I can store the images which is easy to use in my app. I mean should I store it locally or in cloud? If yes which cloud or backend should I use, whichone is good and fully optimized for my flutter app (like mongo, django, firebase etc. ). Will anyone suggest me the best?
Anyone kind of help is appreaciated as I have no prior knowledge about the production part....
Storing Images on a server can be very expensive, since the file sizes are very large compared to the usual data. So if you do not NEED to store them on a server, don't.
Storing images locally is pretty simple. You will want to use the path_provider package https://pub.dev/packages/path_provider . I ll post a function I am using in my current project that does this. You ll see, its pretty simple.
Note: In my Code I pull the file from my server. Obviously leave that part out if you are getting your images from a different source.
Future<File> createFileOfPdfUrl(String fileLocation, String name) async {
final url = Helper.baseUrl + "Files/Newsletter/" + fileLocation;
final filename = url.substring(url.lastIndexOf("/") + 1);
var request = await HttpClient().getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await pathProvider.getApplicationDocumentsDirectory()).path;
File file = new File('$dir/$filename');
await file.writeAsBytes(bytes);
return file;
}
Related
I need to upload a list of images into a storage, but I don't want to upload and await for every single image after the other, because it takes quite some time.
I would like to upload them simultaneously, like in different threads.
There is a way to do achieve multithreading with standard dart async? Or should I use Isolates?
Do you have some sample code?
You can use them in a single future
final results = await Future.wait([
uploadFunction(image1)
uploadFunction(image2)
]);
you can start uploading all images without waiting for the previous one to complete await will be returned once both uploads are completed
You can use Queue
Whats it will do it will hold your actions and you can do other task while uploading images
import 'package:dart_queue/dart_queue.dart';
main() async {
final queue = Queue(parallel: 2);
final result1 = await queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
final result2 = await queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
//Thats it!
}
By using this you dont need to add await.
NOTE: Make sure app is running while this queue is active.
I'm making an Android app, and when using the image picker plugin;
final pickedFile = await ImagePicker().getImage(source: ImageSource.gallery);
File image = File(pickedFile.path);
the 'image' is a copy of the original image in the app's cache, however, I would like to directly use the original image's path to save it in my app because I don't want the apps cache size to grow. I saw that the deprecated method "pickImage" accomplished this (not copying to cache), but the new "getImage" seems to copy automatically and 'image's path is the path of the cached image.
How can I accomplish getting just the original path of the selected image without it being cached? (I'm assuming that using the original file's path would still work to display it in the app with FileImage(File(originalPath)), this is correct assumption?)
On iOS it was never possible to retrieve the original path and on Android it was only possible until SDK 30.
From FAQ of file_picker plugin,
Original paths were possible until file_picker 2.0.0 on Android, however, in iOS they were never possible at all since iOS wants you to make a cached copy and work on it. But, 2.0.0 introduced scoped storage support (Android 10) and with and per Android doc recommendations, files should be accessed in two ways:
Pick files for CRUD operations (read, delete, edit) through files URI and use it directly — this is what you actually want but unfortunately isn’t supported by Flutter as it needs an absolute path to open a File descriptor;
Cache the file temporarily for upload or similar, or just copy into your app’s persistent storage so you can later access it — this is what’s being done currently and even though you may have an additional step moving/copying the file after first picking, makes it safer and reliable to access any allowed file on any Android device.
I have an example for the file_picker package:
var filePath = '';
var fileExtension = '';
var fileName = '';
void buttonOnTap() async {
try {
filePath = await FilePicker.getFilePath(type: FileType.IMAGE);
if (filePath != null) {
fileName = filePath.split('/').last;
fileExtension = fileName.split('.').last;
} else {
filePath = '';
fileName = '';
fileExtension = '';
}
} catch (e) {}
if (filePath != '') {
Image.file(File(filePath), fit: BoxFit.cover);
}
}
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();
I have a sales app develpmented in Flex Builder. For use photos by off-line way, i upload a compressed file with all photos to the site and when need i sincronize with my smartphone. In that process is made a download to the dispositive and exist a responsable plugin to descompress the archive and disponibilize it in apropriate folder to later use.
That compressed file has 500MB size - 6700 photos approximately - and in Flex i have no type of problem to do that.
I'm rewriting the app in Flutter, using a archive package, dont getting the same results. In the descompress process i have problem with Out of memory.
Somebody already faced for something like that ?
Is there an best way to do this ?
I already tried other two alternatives:
- To use the Image.network, but, one of requires is work off-line.
- To save all the photos in assets folder, but i think that is not the best alternative, because the app will get bigger
Thank you in advance for.
Follow the error message and the code
code:
unarchiveAndSave()async{
var zippedFile = await initDir();
var bytes = zippedFile.readAsBytesSync();
var archive = ZipDecoder().decodeBytes(bytes);
for (var file in archive) {
var fileName = '$_dir/${file.name}';
if (file.isFile) {
var outFile = File(fileName);
print('File:: ${outFile.path}');
outFile = await outFile.create();
await outFile.writeAsBytes(file.content);
}
}
print('terminei de descompactar os arquivos');
}
I have been really cracking my head trying to write and read png files into a folder in Windows Phone 8. From few blogs sites and codeplex i found that the there is an extension to the WritableBitmap Class which provides few extra functionalities. ImageTools has PNG encoder and decoder. But I really cant find examples to use them.
What Im trying to achieve here is to create a folder called page and then in it a file called Ink File. I want to convert the bitmap to a PNG and store it there. The bitmap is created from the strokes drawn on a canvas. The class ImageTools provides a function called ToImage to convert the strokes from the canvas to image.
For storing
ExtendedImage myImage = InkCanvas.ToImage();
var encoder = new PngEncoder();
var dataFolder = await local.CreateFolderAsync("Page", CreationCollisionOption.OpenIfExists);
StorageFile Ink_File = await dataFolder.CreateFileAsync("InkFile", CreationCollisionOption.ReplaceExisting);
using (var stream = await Ink_File.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
using (var s = await Ink_File.OpenStreamForWriteAsync())
{
encoder.Encode(myImage, s);
await s.FlushAsync();
s.Close();
}
}
Is this a correct method? I receive some null exceptions for this. How do i find if the image is saved as png. How is this image saved? Is it encoded and saved in a file or is it saved as a png itsef. And how do we read this back?
I have checked out this, this , this and lot more like this.
I'm developing app for WP8
I have used the PNG Writer Library found in ToolStack and it works :)