Image is null after its picked by using image_picker package and saved on local memory (flutter) - flutter

Description:
I'm using (image_picker: ^0.8.5+3) package to pick the images from gallery and camera and then upload them on backend server (django by using django rest framework)
Issue:
Image is getting null outside picker function, even though state has been set by using setSatet(() {}) method
Failed Solutions:
I tried to save the image locally before uploading the image on the backend, But image still shown null once its used or referenced outside picker function
Note: backend API's works fine and i can upload images by using postman
picker function:
// Get image from gallery and store it locally
Future<File?> _getFromGallery() async {
PickedFile? image = await ImagePicker.platform.pickImage(source: ImageSource.gallery);
if (image == null) {
return null;
}
final File file = File(image.path);
final Directory directory = await getApplicationDocumentsDirectory();
final imagepath = directory.path;
final String fileName = path.basename(image.path);
File newImage = await file.copy('$imagepath/$fileName');
setState(() {
_imagelocal = newImage;
print('image.path1');
print(_imagelocal!.path);
});
}
Uploading image function:
_uploadimage() async {
Map<String,String> header = {
"Content-Type":"application/octet-stream)"
};
print("uploaded image invoked");
var request = http.MultipartRequest('POST', Uri.parse('http://192.168.1.15:8000/api/uploadimage'));
// request.files.add(await http.MultipartFile('image',http.ByteStream(image.openRead()).cast(),await image.length(),filename:image.name, contentType: MediaType('image', 'jpg')));
request.files.add(await http.MultipartFile('LoadModelImage',http.ByteStream(_imagelocal!.openRead()).cast(),await _imagelocal!.length(),));
request.headers.addAll(header);
//for completeing the request
var response =await request.send();
//for getting and decoding the response into json format
var responsed = await http.Response.fromStream(response);
final responseData = json.decode(responsed.body);
if (response.statusCode==201) {
print("SUCCESS");
print(responseData);
}
else {
print("ERROR");
}
}

Related

How can I show first time that getting image from firebase storage in my app?

I define pick image and photoUrl variables:
File? image;
String? photoUrl;
This is my pick image method:
Future pickImage(ImageSource source) async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) return;
final imageTemporary = File(image.path);
setState(() {
this.image = imageTemporary;
});
} on PlatformException catch (e) {
print('Failed to pick image : $e');
}
}
This is my upload image function ı upload image with current user ids:
Future uploadFile() async {
final path = '${_auth.currentUser!.uid}.jpg';
final file = File(image!.path);
final ref = FirebaseStorage.instance
.ref()
.child('images/${_auth.currentUser!.uid}.jpg');
task = await ref.putFile(file);
//final url = await ref.getDownloadURL();
//print('Download URLLLLLLLLLLLLLLLLLLLLL : $url');
/*
I saved download image url to setstate method
setState(() {
photoUrl = url.toString();
});
*/
}
This is my download image and init state method, when I upload image to firebase storage first time, ı am getting no object exist at desired reference error, but after ı upload image then I try
to download image and I want to show in image.network it works, How can I fix this error when I try to upload and download first time without error ?
Future downloadImage() async {
final ref = FirebaseStorage.instance
.ref()
.child('images/${_auth.currentUser!.uid}.jpg');
final url = await ref.getDownloadURL();
print('Download URLLLLLLLLLLLLLLLLLLLLL : $url');
setState(() {
photoUrl = url.toString();
});
}
#override
initState() {
// TODO: implement initState
super.initState();
downloadImage();
}
This is my error:
and
this is my storage its empty :
The problem seems to be that you are trying to get the url before uploading the image, Here is what you can do :
uploadImage() async {
final _firebaseStorage = FirebaseStorage.instance;
final _imagePicker = ImagePicker();
PickedFile image;
//Check Permissions
await Permission.photos.request();
var permissionStatus = await Permission.photos.status;
if (permissionStatus.isGranted){
//Select Image
image = await _imagePicker.getImage(source: ImageSource.gallery);
var file = File(image.path);
if (image != null){
//Upload to Firebase
var snapshot = await _firebaseStorage.ref()
.child('images/imageName')
.putFile(file).onComplete;
var downloadUrl = await snapshot.ref.getDownloadURL();
setState(() {
imageUrl = downloadUrl;
// in here you can add your code to store the url in firebase database for example:
FirebaseDatabase.instance
.ref('users/$userId/imageUrl')
.set(imageUrl)
.then((_) {
// Data saved successfully!
})
.catchError((error) {
// The write failed...
});
});
} else {
print('No Image Path Received');
}
} else {
print('Permission not granted. Try Again with permission access');
}
source How to upload to Firebase Storage with Flutter
I hope this will be helpfull

Saving image permenantly after user upload it in flutter

In my flutter app, if the user is signing in for the first time, he will be directed to profile page where he gets to key in his personal details and upload his profile pic. now my issue is with the profile pic. First of all, Im using Image picker package.
Future pickImage(ImageSource source) async {
try {
final image = await ImagePicker().pickImage(
source: source);
if (image == null) return;
final UserImage = File(image.path);
setState(() => this.image = UserImage );
}on PlatformException catch (e){
Utils.showSnackBar(e.message);
}
}
But with this code alone, everytime the app gets restarted the image will be null. So I tried to upload the image to the Firebase Storage when the user picks an image and generate a url:
Future uploadImage () async {
FirebaseStorage storage = FirebaseStorage.instance;
Reference ref = storage.ref().child(userID.toString());
UploadTask uploadTask = ref.putFile(image!);
uploadTask.whenComplete(() async {
url = await ref.getDownloadURL(); }
).catchError((onError){
print(onError);
});
return url;
}
But again every time I restart the app, the url will be null.
What is the best way to save the image permenantly when the user signs in for the first time.
edit: I want to store the image locally so that the user doesnt need an internet connection to load the image everytime he open the app.
Your answers and responses are highly appreciated.
you need to get folder directory first
Future<String> getStorageDirectory() async {
if (Platform.isAndroid) {
return (await getExternalStorageDirectory()).path;
} else {
return (await getApplicationDocumentsDirectory()).path;
}
}
Add image in path
uploadImage() async{
String dir= getStorageDirectory();
File directory = new File("$dir");
if (directory.exists() != true) {
directory.create();
}
final image = await ImagePicker().pickImage(
source: source);
if (image == null) return;
final userImage = File(image.path);
var newFile = await userImage.writeAsBytes(/* image bytes*/);
await newFile.create();
}

How to get Download URL from Firebase Storage in flutter

The Following Code is used to Upload any image from gallery/Camera to Firebase storage. I was successful in uploading the image to storage along with meta data. Now the problem is I am not able to get the download URL of the uploaded image. Tried a lot but didn't find any solution.
FirebaseStorage storage = FirebaseStorage.instance;
final picker = ImagePicker();
PickedFile pickedImage;
File imageFile;
Future<void> _upload(String inputSource) async {
try {
pickedImage = await picker.getImage(
source: inputSource == 'camera'
? ImageSource.camera
: ImageSource.gallery,
maxWidth: 1920);
final String fileName = path.basename(pickedImage.path);
imageFile = File(pickedImage.path);
try {
// Uploading the selected image with some custom meta data
await storage.ref(fileName).putFile(
imageFile,
SettableMetadata(
customMetadata: {
'uploaded_by': 'A bad guy',
'description': 'Some description...'
},
),
);
// Refresh the UI
setState(() {});
} on FirebaseException catch (error) {
print(error);
}
} catch (err) {
print(err);
}
}
Hope You're Doing Well …
You Can Try This Method To Get The URL Of The Image(Any File) From Firebase Storage To Firebase Store And Then You Can Retrieve Image .
class _UploadAdState extends State<UploadAdPage> {
final formKey = GlobalKey<FormState>();
File _myimage;
String imgUrl;
Future getImage1(File chosenimage) async {
PickedFile img =
await ImagePicker.platform.pickImage(source: ImageSource.gallery);
if (chosenimage == null) return null;
File selected = File(img.path);
setState(() {
_myimage = chosenimage;
});
}
// changing the firestore rules and deleteing if request.auth != null;
sendData() async {
// to upload the image to firebase storage
var storageimage = FirebaseStorage.instance.ref().child(_myimage.path);
UploadTask task1 = storageimage.putFile(_myimage);
// to get the url of the image from firebase storage
imgUrl1 = await (await task1).ref.getDownloadURL();
// you can save the url as a text in you firebase store collection now
}
}
I am using in my app this function. Pass image file and download with getDownloadUrl .
Future <String> _uploadphotofile(mFileImage) async {
final Reference storageReference = FirebaseStorage.instance.ref().child("products");
UploadTask uploadTask = storageReference.child("product_$productId.jpg").putFile(imgfile);
String url = await (await uploadTask).ref.getDownloadURL();
return url;
}

Flutter AZURE BLOB IMAGE UPLOAD - How to upload image captured using mobile camera to azure blob storage

I have been working for few since yesterday to try upload an image to azure blob storage taken using mobile camera form iOS/Android device.
I am able to upload the files but for some reason they being corrupted not able to open the image uploaded.
Please check the image error while opening the uploaded image
I am using flutter package http with different approach all work in uploading image file to azure blob store but it gets corrupted somehow , I tried forcing the ContentType to image/jpeg but no help.
Here is code I am using an http API -
takePicture() async {
final pickedFile = await picker.getImage(source: ImageSource.camera);
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
String fileName = basename(pickedFile.path);
uploadFile(fileName, image);
} else {
print('No image selected.');
}
});
}
First approach -->
http.Response response = await http.put(
uri,
headers: {
"Content-Type": 'image/jpeg',
"X-MS-BLOB-TYPE": "BlockBlob",
},
body: image.path,
);
print(response.statusCode);
Using Approach second -->
final data = image.readAsBytesSync();
var dio = Dio();
dio.options.headers['x-ms-blob-type'] = 'BlockBlob';
dio.options.headers['Content-Type'] = 'image/jpeg';
try {
final response = await dio.put(
'$url/$fileName?$token',
data: data,
onSendProgress: (int sent, int total) {
if (total != -1) {
print((sent / total * 100).toStringAsFixed(0) + "%");
}
},
);
print(response.statusCode);
} catch (e) {
print(e);
}
Approach third -->
var request = new http.MultipartRequest("PUT", postUri);
request.headers['X-MS-BLOB-TYPE'] = 'BlockBlob';
request.headers['Content-Type'] = 'image/jpeg';
request.files.add(
new http.MultipartFile.fromBytes(
'picture',
await image.readAsBytes(),
),
);
request.send().then((response) {
uploadResponse.add(response.statusCode);
}, onError: (err) {
print(err);
});
Help here is much appreciated.
If you want to upload the image to Azure Blob Storage in the flutter application, you can use the Dart Package azblob to implement it. Regarding how to use the package, please refer to here.
For example
import 'package:image_picker/image_picker.dart';
import 'package:flutter/material.dart';
import 'package:azblob/azblob.dart';
import 'package:mime/mime.dart';
...
//use image_picker to get image
Future uploadImageToAzure(BuildContext context) async {
try{
String fileName = basename(_imageFile.path);
// read file as Uint8List
Uint8List content = await _imageFile.readAsBytes();
var storage = AzureStorage.parse('<storage account connection string>');
String container="image";
// get the mine type of the file
String contentType= lookupMimeType(fileName);
await storage.putBlob('/$container/$fileName',bodyBytes: content,contentType: contentType,type: BlobType.BlockBlob);
print("done");
} on AzureStorageException catch(ex){
print(ex.message);
}catch(err){
print(err);
}
Unfortunately, the multipart form is causing break of image. I don't know how it works on azure side, because there is little or no information about multipart uploads, but it's clearly broken because of multipart form. I replicated the problem in .net core application and whenever i am using multipart form data to upload image - it is broken. When i am using simple ByteArrayContent - it works. I couldn't find flutter equivalent to ByteArrayContent, so i am lost now :( The package mentioned by #Jim is useless for me, because i want to give clients sas url, so they have permission to upload image on client side. I do not want to store azure storage account secrets in flutter app.
EDIT. I found the solution to send raw byte data with Dio package. You can do that also with http package.
final dio = new Dio();
final fileBytes = file.readAsBytesSync();
var streamData = Stream.fromIterable(fileBytes.map((e) => [e]));
await dio.put(uploadDestinationUrl,
data: streamData,
options: Options(headers: {
Headers.contentLengthHeader: fileBytes.length,
"x-ms-blob-type": "BlockBlob",
"content-type": "image/jpeg"
}));

Flutter form builder package image picker firestore flutter

i am using FormBuilderImagePicker from package Flutter form builder
I want to use the img path but i am not able to do so
sending() async {
var storageimage =
FirebaseStorage.instance.ref().child('/google/google');
var task = storageimage.putFile();
imgurl = await (await task.onComplete).ref.getDownloadURL();
// await Firestore.instance.collection('twst').add(
// {
// 'img': imgurl.toString(),
// },
// );
}
i want to use that function with the imagepicker
but the problem is i am not able to find path to use putfile
To get the path of the FormBuilderImagePicker, the toString() method of the class prints the path.
Here is an example of how you can print in a container the Text field including FormBuilderImagePicker which have the path.
Then you will need to pass the image or file to the putFile method.
You can also use the ImagePicker pickImage class method to get the file.
sending() async {
File image;
try {
//Get the file from the image picker and store it
image = await ImagePicker.pickImage(source: ImageSource.gallery);
// Throws error when you don't select any image or when you don't have permissions
} on PlatformException catch (e) {
return;
}
//Create a reference to the location you want to upload to in firebase
StorageReference reference = FirebaseStorage.instance.ref().child("/google/google");
//Upload the file to Firebase
StorageUploadTask uploadTask = reference.putFile(image);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
// Waits till the file is uploaded then stores the download URL
String url = await taskSnapshot.ref.getDownloadURL();
}