I have been tried to load a image from gallery an keep it permanently in app. But when I move to a different route and return to the image route previously loaded image has been disappeared.
'''
return Scaffold(
appBar: AppBar(
title: const Text('test'),
),
body: ListView(
children: [
ElevatedButton(
child: const Text('Upload a picture'),
onPressed: () async {
try {
final image =
await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) return;
final directory = await getApplicationDocumentsDirectory();
log('imagevalue $image');
final name = basename(image.path);
final imagefile = File('${directory.path}/$name');
final imagePermanent =
await File(image.path).copy(imagefile.path);
setState(() {
_image = imagePermanent;
log('_imageV $_image');
});
} on PlatformException catch (e) {
log(e.toString());
}
},
),
_image != null
? Image.file(
_image!,
height: 160,
width: 160,
fit: BoxFit.fill,
)
: const Icon(Icons.flutter_dash),
],
),
);
}
}
'''
to keep images or any kind of data in your app u should use a database like firbase or mySql to store images then retrieve in in ur app
Related
I am trying to compress image that is picked via file_picker package. I am compressing image with flutter_native_image. But image is not being compressed.
Where have I gone wrong?
P.S - I can't use image_picker package because it stopped working and I had to switch to file_picker.
class UploadSingleImageToFirestore extends StatefulWidget {
const UploadSingleImageToFirestore({super.key});
#override
State<UploadSingleImageToFirestore> createState() =>
_UploadSingleImageToFirestoreState();
}
class _UploadSingleImageToFirestoreState
extends State<UploadSingleImageToFirestore> {
File? _pickedImage;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: appBarTitle(context, 'Upload Single Image'),
backgroundColor: ZayyanColorTheme.zayyanGrey,
body: _pickedImage != null
? Center(
child: Column(
children: [
ANPFormContainer(
fieldTitle: 'Single Image',
subTitle: 'Pick Single Image',
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 140),
child: Image.file(
File(_pickedImage!.path),
height: 300,
width: 300,
),
),
),
addVerticalSpacer(25),
ElevatedButton(
onPressed: () => pickImage(),
child: const Text('Pick Image')),
ElevatedButton(
onPressed: () => _updateMedia(),
child: const Text('Upload Images')),
],
),
)
: InkWell(
onTap: () => pickImage(),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(Icons.add_a_photo),
SizedBox(height: 10),
Text('Tap anywhere to pick images')
],
),
),
),
);
}
pickImage() async {
FilePickerResult? result =
await FilePicker.platform.pickFiles(type: FileType.image);
if (result != null) {
File file = File(result.files.single.path!);
print(file);
compressImage(file);
setState(() {
_pickedImage = file;
});
} else {
print("No file selected");
}
}
compressImage(path) async {
if (_pickedImage == null) return;
File compressedFile = await FlutterNativeImage.compressImage(
path,
quality: 10,
percentage: 20,
targetWidth: 600,
);
return compressedFile;
}
_updateMedia() async {
CollectionReference collectionRef =
FirebaseFirestore.instance.collection('Users');
final coverUrl = await context
.read<FirebaseStorageService>()
.saveCoverInCloudStorage(
file: _pickedImage!,
state: 'Test State',
township: 'Test Township',
propertyType: 'Test House',
propertyid: 'HYG-1234');
return collectionRef
.doc('gMH1s0XUIvWdD2fYfqMvPc915a03')
.update({
'logo': coverUrl,
})
.then((value) => ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Property Info Updated'))))
.catchError((error) => ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('+++ Failed to update user: $error"'))));
}
}
If your requirement is just images, Use image_picker instead of file_picker.
Fetching from image picker
You can use the built in imaqeQuality property from ImagePicker to compress the image. This property takes a value between 0 and 100 and represents a percentage of the original image quality.
File _image;
Future getImage() async {
var image = await ImagePicker.pickImage(
source: ImageSource.gallery,
imageQuality: 25,
);
setState(() {
_image = image;
});
}
Use flutter_native_image to compress
Future<File> compressFile(File file) async{
File compressedFile = await FlutterNativeImage.compressImage(file.path,
quality: 5,);
return compressedFile;
}
Also Refer: Flutter the best way to compress image
I'm trying to find a solution for resizing an image.
The images are picked from a gallery or camera. The problem that I have Is that the image always is not sharp.
This Is How I pick the photo
void _showPickOptionsDialog(BuildContext context, UserData userData) {
final user = Provider.of<Userforid>(context, listen: false);
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text("Pick From Gallery"),
onTap: () {
_loadPicker(ImageSource.gallery, userData);
Navigator.pop(context);
},
),
ListTile(
title: Text("Pick from Camera"),
onTap: () {
_loadPicker(ImageSource.camera, userData);
Navigator.pop(context);
},
),
],
),
),
);
}
Future _loadPicker(ImageSource source, UserData userData) async {
final XFile file =
await picker.pickImage(source: source, imageQuality: 100);
if (this.mounted) {
// This checks if the widget is still in the tree
setState(() {
if (file != null) {
_cropImage(file, userData);
} else {
return null;
}
});
//Navigator.pop(context);
}
}
_cropImage(XFile picked, UserData userData) async {
final user = FirebaseAuth.instance.currentUser.uid;
File cropped = await ImageCropper.cropImage(
sourcePath: picked.path,
aspectRatioPresets: [
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio16x9,
CropAspectRatioPreset.ratio5x4
],
maxWidth: 800,
);
if (cropped != null) {
setState(() {
_pickedImage = cropped;
});
}
if (_pickedImage != null) {
final ref = FirebaseStorage.instance
.ref()
.child('user_profile_pictures')
.child(user + '.jpg');
await ref.putFile(_pickedImage);
final url = await ref.getDownloadURL();
_curenturl = url;
await DatbaseService(uid: user).updateUserData(
...);
}
}
And this is how I display them
Container(
child: ClipRRect(
borderRadius:
BorderRadius.circular(60),
child: Container(
height: 110,
width: 110,
decoration: BoxDecoration(
color: Colors.white,
),
child: _pickedImage != null
? Image.file(
_pickedImage,
fit: BoxFit.cover,
)
: userData.url != null &&
userData.url !=
"profilepictureer"
? Image.network(
userData.url,
fit: BoxFit.cover,
)
: Image.asset(
'assets/profilepictureer.png') // Your widget is here when image is no available.
),
),
decoration: new BoxDecoration(
shape: BoxShape.circle,
border: new Border.all(
color: Colors.black,
width: 1)),
),
So the images are set as user profile photos. Probably a solution will be to upload rounded images like Instagram. So the question that I have is how can a user picks a normal photo from camera or gallery and upload it as rounded?
If not how to solve ghe problem then?
You can simply wrap the widget with a ClipOval with flutter.
Take a look at this doc: Flutter Document
or Try using BoxFit.fill
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
userData.url,
fit: BoxFit.fill,
),
Hey I am using a method for picking photos for user profile picture like that
void _showPickOptionsDialog(BuildContext context, UserData userData) {
final user = Provider.of<Userforid>(context, listen: false);
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text("Pick From Gallery"),
onTap: () {
_loadPicker(ImageSource.gallery, userData);
Navigator.pop(context);
},
),
ListTile(
title: Text("Pick from Camera"),
onTap: () {
_loadPicker(ImageSource.camera, userData);
Navigator.pop(context);
},
),
],
),
),
);
}
Future _loadPicker(ImageSource source, UserData userData) async {
final XFile file =
await picker.pickImage(source: source, imageQuality: 100);
if (this.mounted) {
// This checks if the widget is still in the tree
setState(() {
if (file != null) {
_cropImage(file, userData);
} else {
return null;
}
});
//Navigator.pop(context);
}
}
_cropImage(XFile picked, UserData userData) async {
final user = FirebaseAuth.instance.currentUser.uid;
File cropped = await ImageCropper.cropImage(
sourcePath: picked.path,
aspectRatioPresets: [
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio16x9,
CropAspectRatioPreset.ratio5x4
],
maxWidth: 800,
);
if (cropped != null) {
setState(() {
_pickedImage = cropped;
});
}
if (_pickedImage != null) {
final ref = FirebaseStorage.instance
.ref()
.child('user_profile_pictures')
.child(user + '.jpg');
await ref.putFile(_pickedImage);
final url = await ref.getDownloadURL();
_curenturl = url;
await DatbaseService(uid: user).updateUserData(
...);
}
}
And then I displaying the image like that
Container(
child: ClipRRect(
borderRadius:
BorderRadius.circular(60),
child: Container(
height: 110,
width: 110,
decoration: BoxDecoration(
color: Colors.white,
),
child: _pickedImage != null
? Image.file(
_pickedImage,
fit: BoxFit.cover,
)
: userData.url != null &&
userData.url !=
"profilepictureer"
? Image.network(
userData.url,
fit: BoxFit.cover,
)
: Image.asset(
'assets/profilepictureer.png') // Your widget is here when image is no available.
),
),
decoration: new BoxDecoration(
shape: BoxShape.circle,
border: new Border.all(
color: Colors.black,
width: 1)),
),
So a user picks a photo then he can choose if he wanna crop the image and then im creating a downloadurl which im uploading into cloud firestorm and finally uploading the image into firebase cloud storage.
When ever I wanna display the photo I just calling the url.
The problem that I have is that the image looks pixaled and not sharp.
Like this
Hope anyone can help.
My 2 cents
First, try downloading the image directly from the online storage to your computer to check if it was corrupted during the upload.
Next, use the CircleAvatar widget to check whether the problem is not with the displaying part.
CircleAvatar(
radius: 50.0,
backgroundImage: _pickedImage,
)
image_picker looks fine when i use it in emulator, when it's pressed it works properly but when i install it to my phone it does nothing when i pressed the button for image_picker no camera show just nothing change.
i think it has to be some persmission" things but i don't quite understand with it
method:
var selectedImagePath = ''.obs;
getImage(ImageSource ImageSource) async {
final pickedFile = await ImagePicker().pickImage(source: ImageSource);
if (pickedFile != null) {
selectedImagePath.value = pickedFile.path;
} else {
Get.snackbar('Error', 'No Image Selected');
}
}
display:
Scaffold(
body: SafeArea(
child: Column(
children: [
Obx(
() => Container(
width: double.infinity,
height: 400,
decoration: selectedImagePath == ''
? BoxDecoration(
color: Colors.grey,
)
: BoxDecoration(
color: Colors.grey,
image: DecorationImage(
image: FileImage(
File(
selectedImagePath.value,
),
),
fit: BoxFit.cover
),
),
),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {
getImage(ImageSource.camera);
},
child: Text('Take a photo'),
),
ElevatedButton(
onPressed: () {
getImage(ImageSource.gallery);
},
child: Text('Take from gallery'),
),
],
),
],
),
),
);
This works for me
File? _imageFile;
Future<void> getImage(
ImageSource source) async {
XFile? pickedFile = await ImagePicker()
.pickImage(source: source);
if (pickedFile != null) {
File selected = File(pickedFile.path);
_imageFile = selected;
}
}
Let me know if it works for you.
Here is my code, I'm using Provider Library to manage it.
Step 1:
//File? _image;
String? imgString;
ImagePicker? imagePicker = ImagePicker();
Step 2: Widget Code
Future getImage() async {
final dynamic image =
await imagePicker?.pickImage(source: ImageSource.gallery);
setState(() {
if (image != null) {
YourProvider.myImage = File(image.path);
YourProvider.pickedImage = true;
imgString = YourBaseUrl + YourProvider.myImage!.path;
debugPrint("Image: $imgString");
}
});
}
Step 3: Provider
bool pickedImage = false;
File? myImage;
Why my _image not update?
I need _image properties update when user pick new image from gallery or camera, but when user pick new images I use setState for set new value to _image but it didn't work(didn't update UI).
Here my code I have problem:
Sorry I cant full source because editor of stackoverflow complain to many code.
Statefull Class:
enum ChooseMedia { camera, gallery }
File _image;
void getImage(ChooseMedia media) async {
if (media == ChooseMedia.camera) {
var image = await ImagePicker.pickImage(source: ImageSource.camera);
var pathLocal = await getApplicationDocumentsDirectory();
await image.copy('${pathLocal.path}/profileImage.jpg').then((_) {
setState(() {
_image = image;
});
});
}
if (ChooseMedia.gallery == media) {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
var pathLocal = await getApplicationDocumentsDirectory();
await image.copy('${pathLocal.path}/profileImage.jpg').then((_) {
setState(() {
_image = image;
});
});
}
}
#override
Widget build(BuildContext context) {
return PopupMenuButton(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15))),
onSelected: (ChooseMedia media) {
getImage(media);
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<ChooseMedia>>[
const PopupMenuItem<ChooseMedia>(
value: ChooseMedia.gallery,
child: ListTile(
leading: Icon(
Icons.picture_in_picture,
),
title: Text('From galaxy'),
),
),
const PopupMenuItem<ChooseMedia>(
value: ChooseMedia.camera,
child: ListTile(
leading: Icon(Icons.camera),
title: Text('Take picture'),
),
),
],
child: Container(
decoration: BoxDecoration(),
padding: EdgeInsets.all(7),
child: CircleAvatar(
backgroundImage: _image == null
? AssetImage('assets/images/profile.jpg')
: FileImage(_image))),
);
}
You are mixing 'await' and 'then'
Just do
var copiedImage = await image.copy('${pathLocal.path}/profileImage.jpg');
setState(() {
_image = copiedImage;
});