I'm using Image Picker web which works well. I can display image in Image.memory(), but this image in format Uintlist8. For save in storage need format File, my issue is how to save an image in Firebase Storage.
Web image picker:
class _SecondPageState extends State<SecondPage> {
final _formkey = GlobalKey<FormState>();
Uint8List _image;
getImage() async {
Uint8List tempImg = await ImagePickerWeb.getImage(asUint8List: true);
if (tempImg != null) {
setState(() {
_image = tempImg;
});
}
}
Please Try ....
final _formkey = GlobalKey<FormState>();
Uint8List _image;
getImage() async {
Uint8List tempImg = await ImagePickerWeb.getImage(asUint8List: true);
if (tempImg != null) {
setState(() {
_image = tempImg;
final tempDir = await getTemporaryDirectory();
final file = await new File('${tempDir.path}/image.jpg').create();
file.writeAsBytesSync(_image);
});
}
}
Related
I want to add the function which can upload multiple Photo image via ImagePicker
In this code, I can just upload single photo, not mutiple.
This app operating by flutter, dart and firebase server.
[Code]
void dispose() {
textEditingController.dispose();
super.dispose();
}
File _image;
Future _getImage() async {
var image = await ImagePicker.pickImage(
source: ImageSource.gallery,
maxWidth: 1000,
maxHeight: 1000,
);
setState(() {
_image = image;
});
}
Future _uploadFile(BuildContext context) async {
if (_image != null) {
final firebaseStorageRef = FirebaseStorage.instance
.ref()
.child('post')
.child('${DateTime.now().millisecondsSinceEpoch}.png');
final task = firebaseStorageRef.putFile(
_image,
StorageMetadata(contentType: 'image/png'),
);
final storageTaskSnapshot = await task.onComplete;
final downloadUrl = await storageTaskSnapshot.ref.getDownloadURL();
await Firestore.instance.collection('post').add(
{
'contents': textEditingController.text,
'displayName': widget.user.displayName,
'email': widget.user.email,
'photoUrl': downloadUrl,
'userPhotoUrl': widget.user.photoUrl,
});
}
final images = await _picker.pickMultiImage(
maxHeight: 1024,
maxWidth: 1024,
imageQuality: 50,
);
I created here 3 functions used to pick files from imagePicker and to upload them to firebase storage.
first, pick images from gallery:
final imageFiles = await pickImages();
second, upload the images:
final path = 'path/where/you/want/to/save/your/images';
final imageUrls = uploadImages(imagesFiles, path)
print(imageUrls);
you can now use the images urls to save to firestore
Future<List<File>> pickeImages() async {
ImagePicker picker = ImagePicker();
final images = await picker.pickMultiImage(
maxHeight: 1000, maxWidth: 1000, imageQuality: 90);
List<File> files = [];
if (images == null || images.isEmpty) return [];
for (var i = 0; i < images.length; i++) {
final file = File(images[i].path);
files.add(file);
}
return files;
}
Future<String?> _uploadImageFile(File file, String path) async {
try {
final storage = FirebaseStorage.instance;
TaskSnapshot? taskSnapshot;
final storageRef = storage.ref().child(path);
final uploadTask = storageRef.putFile(file);
taskSnapshot = await uploadTask.whenComplete(() {});
final imageUrl = await taskSnapshot.ref.getDownloadURL();
return imageUrl;
} catch (e) {
throw Exception(e.toString());
}
}
Future<List<String>> uploadImages(
List<File> files,
String path,
) async {
final urls = <String>[];
try {
if (files.isNotEmpty) {
for (var i = 0; i < files.length; i++) {
final file = files[i];
final imagePath = '$path/${Random().nextInt(10000)}.jpg';
final url = await _uploadImageFile(file, imagePath);
urls.add(url!);
}
}
return urls;
} on FirebaseException {
rethrow;
}
}
Instead of using ImagePicker.pickImage, use ImagePicker.pickMultiImage. That gives you a List instead of an XFile. Then you can just upload all images in the list. For instance, add an image parameter to your _uploadFile Function so that its function signature is
Future _uploadFile(BuildContext context, XFile image)
and just upload all images like
for (final image of images) {
_uploadFile(context, image)
}
I have a profile screen that prompts user to enter information and there's a image picker for the profile image.
I use Uint8List to store the picked image and upload to a database.
How do I make an image in assets the default image if the user doesn't select an image?
class _SignUpScreenState extends State<SignUpScreen> {
Uint8List? _image;
#override
void dispose() {...}
void selectImage() async {
Uint8List imageFile = await pickImage(ImageSource.gallery);
setState(() {
_image = imageFile;
});
}
void signupUser() async {
final navigator = Navigator.of(context);
if (_image == null) {
//set default image as profile
showSnackBar('Please select image', context);
return;
}
setState(() {...}
My ImagePicker is as follows:
pickImage(ImageSource source) async {
final ImagePicker _imagePicker = ImagePicker();
XFile? _file = await _imagePicker.pickImage(source: source);
if (_file != null) {
return await _file.readAsBytes();
}
}
showSnackBar(String content, BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(content),
),
);
}
The default image is an SVG as well but I have a png too.
Simply check the null state of Unit8List variable
/// for png assets
_image == null ? Image.asset("<asset file path>") : Image.memory(_image!)
For svg image use flutter_svg package
_image == null ? SvgPicture.asset("<asset file path>") : Image.memory(_image!)
I'm trying to save image picked from ImagePicker and store it in shared preferences and then retrieve it from there but no luck so far
To make my question more specific, how to save an image as a string in shared preference and then later retrieve it
Here is my code
File? profileImage;
void saveData(String key, String value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(key, value);
}
void getData(String key) async {
final prefs = await SharedPreferences.getInstance();
final image = await prefs.getString(key);
setState(() {
profileImage = image; //this would result into error because profileImage expect file type value
});
}
Future pickProfile() async {
final profileImagePicker = await ImagePicker().pickImage(source: ImageSource.gallery);
final File profile = File(profileImagePicker!.path);
final directoryPath = await getApplicationDocumentsDirectory();
final path = directoryPath.path;
final imageFile = await File(profileImagePicker.path).copy('$path/image1.png'); // What am I supposed to do after this step
saveData('profile', path); what value needs to be stored here, it expects a string
setState(() {
profileImage = profile;
});
}
To convert image into String you can use below code
final bytes = imageFile.readAsBytesSync();
String imageString = base64Encode(bytes);
To convert String to Image
Uint8List bytes = BASE64.decode(base64ImageString);
You can use the Image widget to diplay the Image
Image.memory(bytes);
class _EventAdminEditState extends State<EventAdminEdit> {
#override
Widget build(BuildContext context) {
String imageURL = widget.ccaDocument['Image'];
final GlobalKey<FormState> _key = GlobalKey();
final TextEditingController imageURLController = new TextEditingController();
imageURLController.text = imageURL;
void _publishEvent() async {
print(imageURL);
widget.ccaDocument.reference.updateData({
'Name' : name,
'Details': details,
'Location': location,
'RegisterInstructions': registrationInstructions,
'EventTime': eventTime,
'Image' : imageURL
}
Future uploadImage(BuildContext context) async {
final picker = ImagePicker();
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
_image = File(pickedFile.path);
});
StorageReference firebaseStorageRef = FirebaseStorage.instance
.ref()
.child('event_profile/${Path.basename(_image.path)}}');
StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
var dowurl = await (await uploadTask.onComplete).ref.getDownloadURL();
setState(() {
imageURL = dowurl.toString();
});
Hi, Can I ask why the imageURL doesn't change even though I called setState() implicitly.
I tried printing it out to confirm to see if the image URL inside upload image is changed.
ImageURL inside upload image is changed but however the global imageURL in publishEvent is unchanged.
What I am trying to do is to change the image that is being uploaded.
Can someone with me out?
Thank you.
String imageURL = widget.ccaDocument['Image'];
this code is in your build, so everytime you call setState(() {}); this is setting your imageUrl.
You need to use initState and set your imageUrl there
String imageURL;
void initState() {
super.initState();
imageURL = widget.ccaDocument['Image'];
}
I am new to flutter, i am building an app where i need to convert the file(image) generated after using image_picker package to asset image to use in the app.
example code as follows, which creates file(Image)
final Function onSelectImage;
ImageInput(this.onSelectImage);
File _storedImage;
Future<void> _takePicture() async {
final imageFile = await ImagePicker.pickImage(
source: ImageSource.camera,
maxWidth: 600,
);
if (imageFile == null) {
return;
}
setState(() {
_storedImage = imageFile;
});
final appDir = await syspaths.getApplicationDocumentsDirectory();
final fileName = path.basename(imageFile.path);
final savedImage = await imageFile.copy('${appDir.path}/$fileName');
widget.onSelectImage(savedImage);
}
Thanks in advance
You can create an image variable which you can rever to and update when you selected the image.
See the following code:
final Function onSelectImage;
ImageInput(this.onSelectImage);
File _storedImage;
Image _tempImage;
Future<void> _takePicture() async {
final imageFile = await ImagePicker.pickImage(
source: ImageSource.camera,
maxWidth: 600,
);
if (imageFile == null) {
return;
}
setState(() {
_storedImage = imageFile;
});
final appDir = await syspaths.getApplicationDocumentsDirectory();
final fileName = path.basename(imageFile.path);
final savedImage = await imageFile.copy('${appDir.path}/$fileName');
widget.onSelectImage(savedImage);
setState(() {
_tempImage = imageFile;
});
}
#override
Widget build(BuildContext context) {
return _tempImage == null ? Container(child:null) : Image(image: _tempImage);
}