Xamarin - image saved to gallery without date - date

I use this code to save images to the gallery:
Uri uri = new Uri(baseUrl + imageName);
var img = await ImageService.Instance.LoadUrl(baseUrl + "social/social_" + imageName).AsJPGStreamAsync(quality:100);
string fileName = "Social_" + uri.ToString().Split('/').Last();
DependencyService.Get<IMediaService>().SaveImageFromStream(img, fileName);
await DisplayAlert("Saved", "Image saved to gallery!", "Ok");
the problem is, that the images do not have a time in the file, and are stored randomly in the gallery...
How can I add date to the files, so they are saved in the proper order in the gallery?

Just append something like this
DateTime.Now.ToString("MMddyyyyhhmmss");
string fileName = "Social_" + uri.ToString().Split('/').Last() + DateTime.Now.ToString("MMddyyyyhhmmss");
//03312020071656

Related

How to create a Button that allow user to download a specific file Flutter

I create a flutter app and I have this one CSV file that used as a template for user. I want to provide a Button that allow user to download this CSV file, so they can use it to have CSV file that already have our template.
The problem is I don't know if the best way is to first store the file online and get the url and use it on the flutter downloader URL or keep it in the local code asset and refer to that file when user tap the download template button. Currently I'm applying the second option and it doesn't work (I don't know if this option is possible or not), the download always fail. I'm using flutter_downloader package.
How to fix this ?
Here's my code, Is something wrong with my code ?
/// Check if the file exist or not
if (await File(externalDir!.path + "/" + fileName).exists()) {
OpenFilex.open(externalDir!.path + "/" + fileName);
} else {
/// Download the file if it doesn't exist in the user's device
final String localPath = (await getApplicationDocumentsDirectory()).path;
/// Dummy file name I want use (it exist in my asset dir"
const String fileName = 'add.png';
final data = await rootBundle.load('assets/logo/add.png');
final bytes = data.buffer.asUint8List();
final File file = File('$localPath/$fileName');
await file.writeAsBytes(bytes);
/// Download the file
final taskId = await FlutterDownloader.enqueue(
url: '',
savedDir: localPath,
fileName: fileName,
showNotification: true,
openFileFromNotification: true,
);
}
To load a file from the AppBundle and then save it to the users phone, do the following:
Put the file in assets/filename.csv and declare it in your pubspec like this:
flutter:
assets:
- assets/filename.csv
Load the file in your code:
import 'package:flutter/services.dart' show ByteData, rootBundle;
(...)
var data = (await rootBundle.load('assets/filename.csv)).buffer.asInt8List();
Save the data to a file (you need the path-provider package if you want to copy the exact code):
import 'package:path_provider/path_provider.dart' as pp;
(...)
var path = (await pp.getApplicationDocumentsDirectory()).path;
var file = File('$path/filename.csv');
await file.writeAsBytes(data, flush: true);
Edit: As Stephan correctly pointed out, if you want to store the file in the downloads folder, you will find additional information about that here. Thank you Stephan!

Error:: Cannot retrieve length of file, path = '' (OS Error: No such file or directory, errno = 2) using http.MultipartFile.fromPath

I am trying to make a screen that shows information from the database such as the image and other fields to be able to update.
I get a Cannot retrieve length of file, path, (OS Error: No such file or directory, errno = 2) problem.
When I open the camera the photo is updated correctly.
I think the problem appears because it is not a route that you get using the camera and it is a route that is saved from the database.
So when I don't update or dont open the camera in the Image Picker File, the File image is assigned the path of the database.
They are the same routes of the same photo.
I don't know if I have to do something in php before I get the path from the database when I send it to flutter
Example of a new camera path, just used by the camera and a path that I get from the database, previously saved::
I get this route from the camera
File: '/data/user/0/com.example.rati_app/cache/3b4075c7-03df-471b-b8c0-7b88561ab29f32288.jpg'
i get this route from the data base
fzn/3b4075c7-03df-471b-b8c0-7b88561ab29f32288.jpg
code and image::
////////////////// dart flutter ///////////////
Future UpdateProfileUser(RoutePictureProfile) async {
var Url = Uri.parse("http://.....");
var request = await http.MultipartRequest('POST', Url);
var pic = await http.MultipartFile.fromPath('User_image',RoutePictureProfile);
request.files.add(pic);
var response = await request.send();
}
////////////////////////// php ///////////////////////
get the information from database
<?php
include("Database.php");
$consulta = "select User_p,User_name,Usuario_email,user_´picture from user";
$query = $conex->query($consulta);
$data=array();
header("Content-Type: application/json");
while($row = $query->fetch_assoc()){
$data[]=$row;
}
echo json_encode($data,JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$conex->close();
?>
insert the photo camera
<?php
$imagen = $_FILES['User_image']['name'];
$imagePath = 'fzn/'.$imagen;
$tmp_name = $_FILES['User_image']['tmp_name'];
move_uploaded_file($tmp_name,$imagePath);
?>
enter image description here

How can I take multiple photos using camera and save all of it to the application's directory

I tried to take 8 photos in 1 button press with:
String timestamp() => DateTime.now().microsecond.toString();
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/Pictures/CameraApp';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${timestamp()}.jpg';
for(int i = 0; i < 8; i++){
await controller.takePicture(filePath);
}
When i checked the app directory, it seems that the app only save the last taken photo. I need to get all that 8 photos into the directory.
It looks like you're calculating a single string for your filepath, then overwriting it 8 times, rather than calling your timestamp() function for every picture which would give you 8 unique file names.

In Flutter, How to detect the completion of copying file?

I am beginner on Flutter.
I want to do this process,,,
1. save a image file.
2. read the property information of the saved image file.
below is the code for it.
// save a image file.
String mainDir = await getMainDirectory(widget.topic);
String path = mainDir + '/' + count.toString();
image.copy(path);
ImageProperties properties;
try {
// get the property information of the image file.
properties = await FlutterNativeImage.getImageProperties( path);
}
on PlatformException catch(e) {
print( e );
// try again ...
properties = await FlutterNativeImage.getImageProperties(
path);
}
When this code running, sometimes an error is occurred.
the error message is "file is not exist".
So, I have to call "getImageProperties()" function again, and I can get the property.
If I can detect the completion of the file copy, I can make these code better.
Is there any suggestion ?
You can use await to make sure image copy finish
final File newImage = await image.copy(path);

IONIC3 - WriteFile & WriteExistingFile is unable to overwrite the file

I would like to do image annotation for my Ionic Application. So the flow of the app would be using the camera plugin to take a picture and use FabricJs to draw on the image then save the file.
I hit the roadblock when I am trying to save or overwrite the file. Apparently the source "http://localhost:8080/file/data/user/0/***/files/1547183479807.png" file does not update.
The flow of the app
1) Take picture with #ionic-native/camera
2) Copy the file to a local directory
3) Use this.win.Ionic.WebView.convertFileSrc to convert the file name to "http://localhost:8080/file/data/user/0/***/files/1547183479807.png"
4) Push to another page to access the canvas
5) Use the link to setBackground to my canvas (FabricJs)
6) Draw on the image (Manually)
7) Save the file via overwriting the existing file but nothing works from here on.
I tried to
- overwrite with writeFile & writeExisitingFile, did not work.
- removeFile and writeFile and did not work.
- tried converting to ArrayBuffer rather than Blob and did not work
- tried creating another new file, did not work too (it seems like after I push to a new page, all the file functions does not affect the files)
- tried using native cordova but did not work too.
- delete that same files twice, (first time I did not get an error but the second time I got an error saying "File Does not exist" but when I view the source, the file is also there and appearing in my thumbnail on my App.
private copyFileToLocalDir(namePath, currentName, newFileName,id,index) {
this.file.copyFile(namePath, currentName, this.file.dataDirectory, newFileName).then(success => {
const keys = id.split('-');
let filename = this.file.dataDirectory + newFileName;
this.fp = this.win.Ionic.WebView.convertFileSrc(filename) ;
this.navCtrl.push(AnnotationsPage, {
filepath: this.fp,
filename: newFileName
});
this.presentToast("Image Successfully Added",'middle');
}, error => {
this.presentToast('Error while storing file.','middle');
});
}
Annotation.ts
savePicture() {
let image = this.canvas.toDataURL({
format: 'png'
});
this.saveBase64(image);
}
public saveBase64(base64:string):Promise<string>{
return new Promise((resolve, reject)=>{
var realData = base64.split(",")[1]
let blob=this.b64toBlob(realData,"image/png")
this.file.writeFile(this.file.dataDirectory,this.filename,blob,{replace:true})
// this.file.writeExistingFile(this.file.dataDirectory,this.filename, blob)
.then((val)=>{
console.log('Write Info',val)
let fp = this.win.Ionic.WebView.convertFileSrc(this.file.dataDirectory+this.filename) ;
})
.catch((err)=>{
console.log('error writing blob')
console.log(err);
// reject(err)
})
})
}
b64toBlob(b64Data, contentType) {
contentType = contentType || '';
var sliceSize = 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
I check the base64 file, it is working fine (Throw the data to an online converter and it display the picture.
After the function "copyFileToLocalDir", it seems like I am unable to modify the files store in the local directory.
Thanks in advance. Feel free to ask me more question. 7 hours and no result.
Update on the testing, I am doing.
Did File.readAsDataUrl and as expected the file file:///data/user/0/*/files/1547231914843.png updated from the old image to the new edited. (Tested the base64 on some online converter) but it still does not reflect on the source http://localhost:8080/file/data/user/0/***/files/1547231914843.png
Thanks to all those who read through.
After tons of testing, I found out that Ionic Webview's files, will not be updated unless you recall them again (Kind of like a cache and apparently there is no way to reset or flush the cache).
So in my case, I would need to remove the image from the webview and call it out again then it will go back to retrieve again or create another file with another file name and display it.