Image not updated after changing it's File Path in Flutter - flutter

By facing image quality not decreased after compressing it multiples time I thought that plugin is not working. But after dumping file on File Storage during debugging, It was Actually Compressed and Image Quality was decreased by 25 %.
But Image is not Updating after setting it's State. I've read many articles and things. I've used all the things I've Found. I tried to clear Flutter's Image Cache and Painting Binding and Stuff. I also tried to empty temporary directory.
imageCache.clearLiveImages();
PaintingBinding.instance.imageCache.clear();
var appDir = (await getTemporaryDirectory()).path;
Directory(appDir).delete(recursive: true);
Here's My Code. First _imagePath is the image it receives and it's displayed properly. When we compress and update the File Path, Image's State is not changed (Image is not changed).
CircleAvatar(
radius: 150,
backgroundImage: FileImage(File(_imagePath)),
),
TextButton(
child: Text(
'Compress',
style: TextStyle(fontSize: 22),
),
onPressed: () {
setState(() async {
// Compressing File
File compressedFile =
await FlutterNativeImage.compressImage(
_imagePath,
quality: 25,
);
_imagePath = compressedFile.path;
});
},
),

I used Value Notifier of flutter which notifies if value changes for image.

Related

The argument type 'File?' can't be assigned to the parameter type 'String?'. By trying to updatePhotoURL

This error accur while I was trying to do UserCredential;await auth.currentUser!.updatePhotoURL(image); I don’t know If I done anything wrong I can’t figure it out . So if you know help. Thanks
late File? image;
Upload image from gallery:
getFromGallery() async {
XFile? pickedFile = await ImagePicker().pickImage(
source: ImageSource.gallery,
maxWidth: 1800,
maxHeight: 1800,
);
if (pickedFile != null) {
setState(() {
image = File(pickedFile.path);
});
}
}
Here’s the function:
resetProfile(
File? image,
) async {
try {
UserCredential;
await auth.currentUser!.updatePhotoURL(image);
Button to called:
ElevatedButton(
onPressed: () => resetProfile(image),
style: ElevatedButton.styleFrom(
primary: Colors.grey,
onPrimary: Colors.black,
elevation: 0.0,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.zero,
),
),
child: const Text('Confirm'),
),
The error seems pretty clear: updatePhotoURL expects you to pass the URL of the image you want to set for the user, but you are trying to pass a File to it.
If you want to use the local for file the user, you'll first need to upload it somewhere, get a URL to that place, and then pass that URL to updatePhotoURL. One place you can upload such images would be into Cloud Storage through Firebase, as shown here: https://firebase.google.com/docs/storage/ios/upload-files
You are directly passing the file inside a String. Get the download URL of an image and pass it inside the updatePhotoImage URL. This will work.

type 'Future<File>' is not a subtype of type 'File'

Important: I have searched a lot but did not find any solution that I can understand.
I am using photo manager to show images and then after selecting an image I want to navigate to the next screen and show that image there (later I want to upload that image to firebase storage).
So the type of File I am getting from the photo_manager package is Future < File > and I am receiving File from the second screen.
How can I convert future to file?
First Screen:
IconButton(
icon: const Icon(Icons.arrow_forward, color: primaryColor),
onPressed: () {
Get.to(PostDetail(
imgFile:
_controller.mediaList[_controller.selectedImageIndex].file,
));
},
),
Second Screen:
On the second screen, I'm getting File.
final File imgFile;
const PostDetail({this.imgFile});
Source Code:: Add Post Page
So as described in photo_manager docs, you need to get the file from the AssetEntity list before moving to the next page.
So on button pressed to go to next page get the file and then pass it to the Page
Below code should work:
IconButton(
icon: const Icon(Icons.arrow_forward, color: primaryColor),
onPressed: () async {
File file = await _controller.mediaList[_controller.selectedImageIndex].file; // image file
Get.to(PostDetail(
imgFile: file,
));
},
),
File and Future<File> are 2 different things. the File is a variable that its value is in the present. but Future<File> as its name suggests, its value exist in the Future which means its value takes some time to reach you.
for example, if you send a request to a webserver, the response takes some time to reach you. so, in that case the response is a Future.
in your case the image you are trying to get is supplied in a way that it takes time. to get the File from Future<File> you have to wait. So before sending the file to this Screen, use an async and wait to turn the Future<File> to File. (i dont know how you get the file)
for example,
File myFile = await getFileorWhaterver();
Your _controller.mediaList[_controller.selectedImageIndex].file is a Future<File> means that the value of the File is promised to be returned sometimes in the future. This usually because you are doing a network call asynchronously to get the data from API.
In order to convert it to File, you need to await till the moment that value is available. However you cannot do an async/await within the UI, that's why Flutter provide a widget named FutureBuilder to wait for a certain Future value, then let you use that value in the UI.
In your case, you can do this:
FutureBuilder(
future: _controller.mediaList[_controller.selectedImageIndex].file,
builder: (context, snapshot) {
return IconButton(
icon: const Icon(Icons.arrow_forward, color: primaryColor),
onPressed: () {
if (snapshot.hasData)
Get.to(PostDetail(imgFile: snapshot.data));
},
);
})

Flutter remove image after upload using image_picker package

I have managed to upload an image using the image picker package as shown below:
final picker = ImagePicker();
Future selectPhoto() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
_image = File(pickedFile.path);
});
}
The image has been displayed on the device where I have a remove button which I can use to remove the image and upload another before saving it.
child: Container(
height: height * 0.2,
width: width * 0.2,
child: Image.file(
_image,
fit: BoxFit.fill,
),
),
My question is how can I remove the image from cache as this piece is not working
onTap: () {
setState(() {
imageCache.clear();
print('removes $_image');
});
},
You have a misunderstanding of what the cache is compared to explicitly storing a file in memory with your code. Flutter may store images that you use in widgets in a cache so that they may load faster in the future. imageCache.clear(); does clear the cache and is likely doing it's work in your code. However, your method of checking if the image is still cached is flawed.
imageCache.clear(); only clears the cache, it does not delete the file that you're passing to the Image.file widget. This means that _image(the file variable you have stored in memory) will persist even over the cache clearing. To truly delete this image you could use the delete method or if you just want to stop showing the image, deference the file by setting the file reference to null:
_image = null;
Solved it by calling a method within the button which had set state method where the path was returned back to null
clearimage() {
setState(() {
_image = null;
});
}

'file.existsSync()': is not true

I am going to store an image in firebase storage. When I send file through image picker then its working fine. But when I manually pass link of image then it is showing an error that says:
'package:firebase_storage/src/storage_reference.dart':
Failed assertion: line 62 pos 12: 'file.existsSync()': is not true.
I am writing following code:
File image = File("assets/img/pic.jpg");
final StorageReference firebaseStorageRef =
FirebaseStorage.instance.ref().child('image');
InkWell(
child: Text("Tap to Upload"),
onTap: () {
firebaseStorageRef.putFile(image);
},
),
The error says it, the file doesn't exists, before doing that you should check if the file is there or create it if it's not
InkWell(
child: Text("Tap to Upload"),
onTap: () async {
File image = await File("assets/img/pic.jpg").create();
// it creates the file,
// if it already existed then just return it
// or run this if the file is created before the onTap
// if(image.existsSync()) image = await image.create();
firebaseStorageRef.putFile(image);
},
),
Also I'm not sure if you can change/create files in the assets folder, if that doesn't work maybe try to put the file in a temp directory of your app

Flutter : fetch image from picture Directory

I'm working with saved image from Url with Gallery Saver. Everything it's oke , i can insert image from URL, but i don't know how to fetch image from picture Directory .
It's different about getApplicationDocumentsDirectory() or getExternalStorageDirectory() ?
I want to display the image that was just saved.
Any solution ?
Save image Code :
void _testSaveImage() async {
String path = "${Urls.BASE_API_IMAGE}/berita/${widget.gambarBerita}";
GallerySaver.saveImage(path).then((bool success) {
print('Success add image $path');
}).catchError((onError) {
print('Error add image $path');
});
}
Location Image saved
Then just return the path you have and use a Image.file() widget to display it, lets say you have a Column():
Column(children: <Widget>[
[...]
Text('Here is my image:'),
if (path.isNotEmpty && path != null)
SizedBox(
height: 200,
width: 200,
child: Image.file(File(path),
),
Text('Caption of the image'),
[...]
),
Docs for Image class here
Load local saved images using path and use it
var file = new File('path');
Image.file(file )