How can I display a Carousel framed by taking pictures in the moment?
This carousel needs a function to remove photos if needed. And an indicator of what image I'm seeing.
I'm using packages: 'image_picker' to get the photos from gallery or camera. And the 'carousel_slider' package to display the carousel.
And so, if there isn't a photo there isn't a carousel.
The problem I get is that the second photo replaces the first... the third replaces the second and the first, I mean the next photo will replace the previous photos. Also, I can't remove the photos from the carousel, and I can't display the indicators for the image I'm looking at either.
Here are the functions I run to take the pictures:
_takePicture() async {
File auxiliarFile;
final ImagePicker _picker = ImagePicker();
XFile imageFile = await _picker.pickImage(
source: ImageSource.camera, maxWidth: 600) as XFile;
setState(() {
_storedImage = File(imageFile.path);
});
auxiliarFile = _storedImage!;
final appDir = await syspath.getApplicationDocumentsDirectory();
String fileName = path.basename(_storedImage!.path);
final savedImage = await _storedImage!.copy('${appDir.path}/$fileName');
listImages.add(auxiliarFile);
}
_chosePicture() async {
final ImagePicker _picker = ImagePicker();
XFile imageFile = await _picker.pickImage(
source: ImageSource.gallery,
) as XFile;
setState(() {
_storedImage = File(imageFile.path);
});
final appDir = await syspath.getApplicationDocumentsDirectory();
String fileName = path.basename(_storedImage!.path);
final savedImage = await _storedImage!.copy('${appDir.path}/$fileName');
listImages.add(savedImage);
}
To display the carousel I tried:
_storedImage != null
? Column(
children: [
CarouselSlider(
options: CarouselOptions(
enableInfiniteScroll: false,
enlargeCenterPage: true,
enlargeFactor: 0.25,
),
items: listImages.map((i) {
return Builder(builder:
(BuildContext context) {
return Container(
width: MediaQuery.of(context)
.size
.width *
0.75,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10),
border: Border.all(
color: Colors.black87),
color: Colors.grey[350],
),
child: OutlinedButton(
onPressed: _showDeleteDialog,
onLongPress: () =>
_showDeleteDialog(),
child: Image.file(
(_storedImage!),
),
),
);
});
}).toList(),
),
Padding(
padding: const EdgeInsets.all(8),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: map<Widget>(listImages,
(index, url) {
return InkWell(
onTap: () {
setState(() {
_pageController
.jumpToPage(index);
currentIndex = index;
});
},
child: Container(
width: 10,
height: 10,
margin: const EdgeInsets
.symmetric(
vertical: 10,
horizontal: 5,
),
decoration:
const BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey,
),
),
);
}),
),
),
],
)
: const Text(
'No image',
style: TextStyle(
fontWeight: FontWeight.bold,
),
)
Related
I have created a variable
List<Xfile> imageList;
using this variable I have showed the selected images in GridView.Builder and uploaded them.
But I want to store those uploaded images in this List to show them again in GridView.Builder.
Means How to store images from imageUrls in List
How can I achieve this?
Follow as follows:
Variables
final picker = ImagePicker();
File? file;
XFile? pickedImage;
bool isLoading = false;
List<File?> fileList = [];
Method to select image from gallery
Future pickImageFromGallery() async {
pickedImage = await picker.pickImage(source: ImageSource.gallery);
setState(() {
file = File(pickedImage!.path);
fileList.add(file);
});
}
And place in gridview as follows:
GridView.builder(
itemCount: fileList.length,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (BuildContext context, int i) {
return Container(
padding: const EdgeInsets.all(10),
child: Stack(
children: <Widget>[
SizedBox(
height: 100,
width: 100,
child: Image.file(File(fileList[i]!.path),fit: BoxFit.cover,),
),
Positioned(
right: 1,
child: GestureDetector(
onTap: () {
setState(() {
dltImages(fileList[i]);
});
},
child: const Icon(Icons.cancel, color: Colors.red),
))
],
),
);
},
),
Find full code at:
https://github.com/nbnD/image_picker_flutter/blob/master/lib/homepage.dart
I do like this if there is multi images upload
class PickImagesPage extends StatefulWidget {
const PickImagesPage({super.key, required this.initialUrls});
final List<String> initialUrls;
#override
State<PickImagesPage> createState() => _PickImagesPageState();
}
class _PickImagesPageState extends State<PickImagesPage> {
#override
void initState() {
urls = widget.initialUrls;
super.initState();
}
List<String> urls = [];
List<File> files = [];
List<String> removedUrls = [];
final Repo repo = Repo();
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final style = theme.textTheme;
final scheme = theme.colorScheme;
return LoadingLayer(
child: Scaffold(
bottomNavigationBar: Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 24),
child: ElevatedButton(
onPressed:
files.isNotEmpty || widget.initialUrls.length != urls.length
? () async {
try {
await repo.uploadImages(
files: files,
urls: urls,
removedUrls: removedUrls,
);
Navigator.pop(context);
} catch (e) {
AppSnackbar(context).error(e);
if (kDebugMode) {
print(e);
}
}
}
: null,
child: const Text(Labels.save),
),
),
appBar: AppBar(
title: const Text(
Labels.ambienceImages,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
final List<XFile> pickedFiles = await pickImages();
if (pickedFiles.isNotEmpty) {
setState(() {
files.addAll(pickedFiles.map((e) => File(e.path)));
});
}
},
child: const Icon(Icons.add),
),
body: GridView.count(
padding: const EdgeInsets.all(12),
crossAxisCount: 2,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
children: [
...urls
.map(
(e) => GestureDetector(
onTap: () {
setState(() {
urls.remove(e);
removedUrls.add(e);
});
},
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: scheme.surfaceVariant.withOpacity(0.5),
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: NetworkImage(e),
),
),
),
),
)
.toList(),
...files
.map(
(e) => Container(
clipBehavior: Clip.antiAlias,
alignment: Alignment.topRight,
decoration: BoxDecoration(
color: scheme.surfaceVariant.withOpacity(0.5),
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: FileImage(e),
),
),
child: SizedBox(
height: 40,
width: 40,
child: RawMaterialButton(
elevation: 0,
focusElevation: 0,
hoverElevation: 0,
shape: const CircleBorder(),
fillColor: theme.cardColor.withOpacity(0.5),
onPressed: () {
setState(() {
files.remove(e);
});
},
child: const Icon(Icons.remove),
),
),
),
)
.toList(),
GestureDetector(
onTap: () async {
final List<XFile> pickedFiles = await pickImages();
if (pickedFiles.isNotEmpty) {
setState(() {
files.addAll(pickedFiles.map((e) => File(e.path)));
});
}
},
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: scheme.surfaceVariant.withOpacity(0.5),
borderRadius: BorderRadius.circular(20),
),
child: Stack(
children: const [
Center(
child: Icon(Icons.add),
),
PickImageLabel(),
],
),
),
),
],
),
),
);
}
}
class Repo {
Future<void> uploadImages(
{required List<String> urls,
required List<File> files,
required List<String> removedUrls}) async {
List<String> newUrls = [];
for (var file in files) {
final url = await upload(file);
newUrls.add(url);
}
for (var url in removedUrls) {
await deleteImage(url);
}
await saveImages(urls + newUrls);
}
}
how to preview an image is to be chosen from gallery or camera in flutter with the new version of image_picker where
PickedFile image = await _picker.getImage(...)
is replace with
final XFile? photo = await _picker.pickImage(source: ImageSource.camera);
so photo must be displayed when it is selected properly
You can do it by using dialog in flutter.
Here is how I dealt with it.
onLongPress: () {
showDialog(
context: context,
builder: (ctx) {
final width = ctx.getWidth(1);
final height = ctx.getHeight(1);
return AlertDialog(
content: Stack(
children: [
SizedBox(
width: width * 0.9,
height: height * 0.7,
child: Image.network(
food.imageUrl,
fit: BoxFit.fill,
),
),
GestureDetector(
onTap: () => Navigator.pop(context),
child: Padding(
padding: const EdgeInsets.all(3.0),
child: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.5),
shape: BoxShape.circle),
child: Icon(
CupertinoIcons.xmark_circle,
color: Colors.white.withOpacity(0.9),
size: 40,
),
),
),
)
],
),
insetPadding: EdgeInsets.zero,
contentPadding: EdgeInsets.zero,
clipBehavior: Clip.antiAliasWithSaveLayer,
);
},
);
},
You can preview image which you select from gallery or camera as below :
Image.file(
File("file path will be here"), // You can access it with . operator and path property
fit: BoxFit.cover,
)
convert to file:
File newPhoto = File(photo.path);
Use:
Image.file(newPhoto);
I used image_pickers package much easier
late File imageFile = File("");
bool isloaded = false;
ElevatedButton(
onPressed: () => pickImageFromCamera(),)
Padding(
padding: const EdgeInsets.all(8.0),
child: !isloaded
? Image.network(
"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ac/No_image_available.svg/2048px-No_image_available.svg.png")
: Image.file(imageFile)),
void pickImageFromCamera() async {
List<Media>? res = await ImagesPicker.openCamera(
pickType: PickType.image,
);
print(res);
if (res != null) {
print(res[0].path);
setState(() {
imageFile = File(res[0].path);
isloaded = true;
setState(() {});
});
} else {
setState(() {
isloaded = false;
});
}
}
I'm trying to pick an image from device and store it on firebase and display it in chat screen. But, whenever I'm using this file its showing following error. Last time when I used File there was no posational arg errors . Is it due to new update?
Here's my debug console
here's my chatroom source code
import 'dart:html';
import 'dart:typed_data';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class ChatRoom extends StatefulWidget {
final Map<String, dynamic> userMap;
final String chatRoomId;
ChatRoom({required this.chatRoomId, required this.userMap});
#override
State<ChatRoom> createState() => _ChatRoomState();
}
class _ChatRoomState extends State<ChatRoom> {
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final TextEditingController _massage = TextEditingController();
File? imageFile;
Future getImage() async {
ImagePicker _picker = ImagePicker();
await _picker.pickImage(source: ImageSource.gallery).then((xFile) {
if (xFile != null) {
imageFile = File(xFile.path);
}
});
}
onSendMassage() async {
if (_massage.text.isNotEmpty) {
Map<String, dynamic> massages = {
"sendby": _auth.currentUser!.displayName,
"massage": _massage.text,
"time": FieldValue.serverTimestamp(),
"type": "text"
};
await _firestore
.collection("chatroom")
.doc(widget.chatRoomId)
.collection("chat")
.add(massages);
_massage.clear();
} else {
_firestore
.collection('chatroom')
.doc(widget.chatRoomId)
.collection('chats')
.orderBy("time", descending: false)
.snapshots();
print("please input some massage");
}
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
leading: new Container(
child: new IconButton(
icon: new Icon(Icons.arrow_back_ios),
onPressed: () {/* Your code */},
),
),
title: Text('username'),
backgroundColor: Colors.grey[850],
),
body: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 16,
),
Container(
height: size.height / 1.25,
width: size.width,
child: StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection('chatroom')
.doc(widget.chatRoomId)
.collection('chat')
.orderBy("time", descending: false)
.snapshots(),
builder: (BuildContext context, snapshot) {
if (snapshot.data != null) {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
Map<String, dynamic> map = snapshot.data!.docs[index]
.data() as Map<String, dynamic>;
return messages(size, map, context);
},
);
} else {
return Container(
child: Center(
child: Text('data'),
),
);
}
},
),
),
Container(
height: size.height / 10,
width: size.width,
alignment: Alignment.center,
child: Container(
height: size.height / 12,
width: size.width / 1.1,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
PhysicalModel(
color: Colors.white,
elevation: 42,
shadowColor: Color.fromARGB(255, 64, 64, 65),
borderRadius: BorderRadius.circular(20),
child: Container(
height: size.height / 16,
width: size.width / 1.3,
child: TextField(
controller: _massage,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(12),
border: InputBorder.none,
suffixIcon: IconButton(
onPressed: () {},
icon: Icon(Icons.photo),
),
hintText: "Send Message",
),
),
),
),
IconButton(
icon: Icon(
Icons.arrow_circle_right_rounded,
size: 38,
),
onPressed: onSendMassage),
],
),
),
)
],
),
),
);
}
}
Widget messages(Size size, Map<String, dynamic> map, BuildContext context) {
final FirebaseAuth _auth = FirebaseAuth.instance;
return map['type'] == "text"
? Container(
width: size.width,
alignment: map['sendby'] == _auth.currentUser!.displayName
? Alignment.centerRight
: Alignment.centerLeft,
child: Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 14),
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.blue,
),
child: Text(
map['massage'] ?? "",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
),
)
: Container(
height: size.height / 2.5,
width: size.width,
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 5),
alignment: map['sendby'] == _auth.currentUser!.displayName
? Alignment.centerRight
: Alignment.centerLeft,
);
}
id now to give in map arg I don't have any use of map here
First of all, you are combining the Future.then, with the async/await syntax, which, is not correct in this case.
When it comes to Future's (which are the equivalent of Promise's if you are used to Javascript), if you await them, there's no need to use the then method.
In this case, you should do:
Future getImage() async {
ImagePicker _picker = ImagePicker();
// Use final if you won't reassing the variable
final XFile file = await _picker.pickImage(source: ImageSource.gallery);
if (file != null && file.path != null) {
imageFile = File(file.path);
}
}
We are awaiting the result and then assigning it to the variable. Alternatively, if you want to use the Future.then syntax, the method should be:
Future getImage() {
ImagePicker _picker = ImagePicker();
// Use final if you won't reassing the variable
_picker.pickImage(source: ImageSource.gallery).then((file) {
if (file != null && file.path != null) {
imageFile = File(file.path);
}
})
}
See as the method signature does not include the async keyword.
I'm getting the image from the image_picker package and loading the image in CircleAvatar but image is not filling across the circle. I have used boxfit.fill in the ClipRRect and also in the ClipOval.
import 'package:image_picker/image_picker.dart';
class EditProfileScreen extends StatefulWidget {
static const String routename = "/EditProfileScreen";
const EditProfileScreen({Key? key}) : super(key: key);
#override
_EditProfileScreenState createState() => _EditProfileScreenState();
}
class _EditProfileScreenState extends BaseState<EditProfileScreen> {
final ImagePicker _picker = ImagePicker();
XFile? _imageFileSelected;
set _imageFile(XFile? value) {
_imageFileSelected = value == null ? null : value;
}
void _onImageButtonPressed(ImageSource source,
{BuildContext? context, bool isMultiImage = false}) async {
try {
final pickedFile = await _picker.pickImage(
source: source, maxHeight: 160, maxWidth: 200);
setState(() {
_imageFile = pickedFile;
});
} catch (e) {
setState(() {
_pickImageError = e;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppWidgets.backgroundColor,
appBar: AppWidgets.appbar(text: "Edit Profile", actionWidgets: []),
body: SingleChildScrollView(
child: Container(
margin: EdgeInsets.fromLTRB(20, 16, 20, 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Column(
children: [
CircleAvatar(
child: ClipRRect(
borderRadius: BorderRadius.circular(48),
child: (_imageFileSelected?.path == null)
? Image.network(
profileImagePath,
)
: Image.file(
File(_imageFileSelected!.path),
),
),
radius: 50.0,
),
SizedBox(
height: 10,
),
TextButton(
onPressed: () {
_onImageButtonPressed(ImageSource.gallery,
context: context);
},
child: AppWidgets.text(
string: 'Change Photo',
weight: FontWeight.w500,
textColor: AppWidgets.buttonColor,
size: 16),
),
],
),
),
),
);
}
Note:
I have used boxfit no luck.
I tried clipoval in the child didn't work.
I tried to put images in backgroundImage and foregroundImage unable to do
Instead of using circleavatar you can use Container with background property Try this code.
Container(
height: 88.5.h,
width: 88.5.w,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: CachedNetworkImageProvider(
state.details["profile_photo"]),
shape: BoxShape.circle,
border: Border.all(
color: ColorConstant.buttonColor,
width: 5.w)),
),
I use this to store the updated picture locally.
ps. this already has a picture which can be changed but you can just use background color to hold instead.
File _image;
String _imagepath;
Future _getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
if (image != null) {
var cropped = await ImageCropper.cropImage(
sourcePath: image.path,
maxHeight: 100,
maxWidth: 100,
aspectRatio: CropAspectRatio(ratioX: 1, ratioY: 1),
cropStyle: CropStyle.circle,
compressQuality: 100,
);
this.setState(() {
_image = cropped;
});
saveImage(_image.path);
}
}
void saveImage(path) async {
SharedPreferences saveimage = await SharedPreferences.getInstance();
saveimage.setString('imagepath', path);
}
void LoadImage() async {
SharedPreferences saveimage = await SharedPreferences.getInstance();
setState(() {
_imagepath = saveimage.getString('imagepath');
});
}
#override
void initState() {
// TODO: implement initState
super.initState();
LoadImage();
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _getImage,
child: Container(
//padding: EdgeInsets.all(2),
decoration: BoxDecoration(
border: Border.all(
color: Colors.white,
width: 5.0,
),
shape: BoxShape.circle,
),
child: _imagepath != null
? CircleAvatar(
backgroundImage: FileImage(File(_imagepath)),
radius: 60,
)
: CircleAvatar(
backgroundImage: _image != null
? FileImage(_image)
: AssetImage('assets/mypic1.jpg'),
backgroundColor: Colors.blue[200],
radius: 60,
),
),
);
I am trying to enable to the app user to change his/her profile picture and upload it via camera or gallery, I used
the image picker package for this purpose,
this is my code snippet:
`
class ProfilePic extends StatefulWidget {
const ProfilePic({
Key key,
}) : super(key: key);
#override
_ProfilePicState createState() => _ProfilePicState();
}
class _ProfilePicState extends State<ProfilePic> {
File image = new File("");
final _picker = ImagePicker();
#override
Widget build(BuildContext context) {
return SizedBox(
height: 115,
width: 115,
child: Stack(
fit: StackFit.expand,
overflow: Overflow.visible,
children: [
CircleAvatar(
backgroundImage: AssetImage(image.uri.toFilePath()),
// child: ClipRRect(
// borderRadius: BorderRadius.circular(50),
// child: image != null
// ? Image.file(
// image,
// width: 115,
// height: 115,
// fit: BoxFit.fitHeight,
// )
// : Container(
// decoration: BoxDecoration(
// color: Colors.grey[100],
// borderRadius: BorderRadius.circular(50)),
// width: 100,
// height: 100,
// child: Icon(
// Icons.camera_alt,
// color: Colors.grey[800],
// ),
// ),
// ),
),
Positioned(
right: -16,
bottom: 0,
child: SizedBox(
height: 46,
width: 46,
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
side: BorderSide(color: Colors.white),
),
color: Color(0xFFF5F6F9),
onPressed: () {
_showPicker(context);
},
child: SvgPicture.asset("icons/cameraIcon.svg"),
),
),
)
],
),
);
}
_imgFromCamera() async {
PickedFile pickedFile =
await _picker.getImage(source: ImageSource.camera, imageQuality: 50);
setState(() {
image = File(pickedFile.path);
});
}
_imgFromGallery() async {
PickedFile pickedFile =
await _picker.getImage(source: ImageSource.gallery, imageQuality: 50);
setState(() {
image = File(pickedFile.path);
});
}
void _showPicker(context) {
showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return SafeArea(
child: Container(
child: new Wrap(
children: <Widget>[
new ListTile(
leading: new Icon(Icons.photo_library),
title: new Text('Gallerie'),
onTap: () {
_imgFromGallery();
Navigator.of(context).pop();
}),
new ListTile(
leading: new Icon(Icons.photo_camera),
title: new Text('Caméra'),
onTap: () {
_imgFromCamera();
Navigator.of(context).pop();
},
),
],
),
),
);
});
}
}
`
PS: I am using Chrome for debugging.
Its select the image from the device but doesn't change the state to upload the image, am asking if it is a flutter web related problem so in a real device or emulator can work smoothly?
Any suggestion please.
AssetImage takes asset files that you have referenced in your pubspec.yaml. you should use FileImage instead if you are trying to display images from the camera or gallery.
example: FileImage(image)
You can read more here