Using the play_games extension, I'm having trouble returning the user's profile image.
Use the method below to login and set the state with the return of the user's data.
Image provider: NetworkImage ("content: //com.google.android.gms.games.background/images/f56551ac/42", scale: 1.0)
// Google Play Games stance
final GameServices gameservices = GameServices();
Account profile;
ui.Image profileimage;
void _login() async {
final res = await gameservices.login();
final resimage = await res.hiResImage;
setState(() {
profile = res;
profileimage = resimage;
});
print(profileimage);
}
In the widget I'm in the form of NetworkImage, but it's still not rendering on the screen.
this error: The argument type 'Image' can't be assigned to the parameter type 'String'.
Container(
width: 128,
height: 128,
padding: EdgeInsets.all(8),
child: CircleAvatar(
backgroundImage: NetworkImage(this.profileimage != null ? this.profileimage : 'https://api.adorable.io/avatars/128/')
),
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle
),
),
[ RESOLVED!!! ]
Change my code and play_games returns type vars.
Lets go:
Future<Uint8List> get hiResImage async =>
await _fetchToMemory(await _channel.invokeMethod('getHiResImage'));
Future<Uint8List> get iconImage async =>
await _fetchToMemory(await _channel.invokeMethod('getIconImage'));
}
Future<Uint8List> _fetchToMemory(Map<dynamic, dynamic> result) {
Uint8List bytes = result['bytes'];
if (bytes == null) {
print('was null, mate');
return Future.value(null);
}
// Completer<Image> completer = new Completer();
// decodeImageFromList(bytes, (image) => completer.complete(image));
return Future.value(bytes);
}
And my code, only this change:
Uint8List profileimage;
Flutter is yelling at you because you gave it a URL with protocol content://, when it expects http:// or https:// for a NetworkImage widget. See documentation at: https://flutter.dev/docs/cookbook/images/network-image
This happen because google provide encoded image. In android we can use ImageManager for that as google suggest.
In flutter there are mechanism for getting Future<Image> from hiresImageUri. Check here.
Use Something like below,
profile.hiResImage.then((Image result){
//here you can get image in result
});
Related
I have side menu in an app in flutter. The circle avatar is supposed to show a default profile picture since user has not set one. When I first install it, it should look like this:
But this is how it looks like when I first install it....
I want it to show default profile photo instead of blue container.
This is the code :
GestureDetector(
onTap: () async {
newphoto = await Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => ProfilePage(
uname: context
.read<ProfileDetails>()
.name //username,
))));
saveimageside(newphoto);
},
child: profileimage != ''
? CircleAvatar(
backgroundImage:
FileImage(File(profileimage)),
radius:
MediaQuery.of(context).size.height *
0.05,
)
: CircleAvatar(
backgroundImage: const AssetImage(
'assets/profile1.png'),
radius:
MediaQuery.of(context).size.height *
0.05,
)),
Outside the build I have :
String profileimage = '';
saveimageside(path) async {
SharedPreferences saveimageside = await SharedPreferences.getInstance();
setState(() {
saveimageside.setString("imagePathside", path);
});
}
loadimageside() async {
SharedPreferences saveimageside = await SharedPreferences.getInstance();
setState(() {
profileimage = saveimageside.getString("imagePathside").toString();
});
}
called loadimagesside in initState
This code is not fully written by me but someone before me.
The blue container is replaced by default image only when I use remove profile picture feature which sets the path to '' Thats okay but I want the app to show default when user first installs it also
You have checked if its empty but for example when you first opened the app without setting the path then loadimageSide() method is called which will get a null as a result and its saved in the variable profileImage. So now the value of profileImage is "null";
You can manage it when you get the image
loadimageside() async {
SharedPreferences saveimageside = await SharedPreferences.getInstance();
setState(() {
profileimage = saveimageside.getString("imagePathside") ?? "";
});
}
Now if the image is null then it will assign an empty string.
How do I load AssetImage or check if it exists? The data is coming from the api, so I cannot list all the file paths as constants.
As an example path maybe be 'assets/images/${card.imageType}.png' where card.inageType is a variable.
...
child: Image(
height: 60.0,
image: Utils.getImage('assets/images/card-${card.category}.png'),
),
...
For my getImage function, I tried 2 kinds but not working
Method 1: Using File: The existsSync method is always false. Keep in mind the await async cannot work as the Image widget is expecting not a Future
static dynamic getImage(path) {
File f = File(path);
return f.existsSync()
? FileImage(f)
: const AssetImage('assets/images/default.png');
}
}
Method 2: Using try catch: The exceptions is not being caught
static AssetImage getImage(path) {
AssetImage image;
try {
image = AssetImage(path);
} catch (e) {
image = const AssetImage('assets/images/default.png');
}
return image;
}
You can use something like this to check if an asset exists:
// example: 'assets/check_green.png'
Future<bool> checkIfAssetExists(String fullAssetPath) async {
final Uint8List encoded = Utf8Codec()
.encoder
.convert(Uri(path: Uri.encodeFull(fullAssetPath)).path);
// returns null if an asset is not found
final ByteData? asset = await ServicesBinding.instance!.defaultBinaryMessenger
.send('flutter/assets', encoded.buffer.asByteData());
return asset != null;
}
You can run this in your initState and then use AssetImage confidently.
As for the exception not being caught, it probably means than an Error was throw which is different from Exceptions
You can check if a file exists asynchronously with this code:
import 'dart:io';
File("path/to/file").exists()
or checking it synchronously:
import 'dart:io';
File("path/to/file").existsSync()
Update:
isPathExists() function is called from initState.
AssetBundle is used for to obtain asset inside asset folder. You can insert anything to menubanner.png if it exists, the image will be assigned to variable and if it does not, an exception throws.
late Image image;
isPathExists() async {
try {
var assetbundle = DefaultAssetBundle.of(context);
ByteData res = await assetbundle.load('assets/images/menubanner.png');
var list = Uint8List.sublistView(res);
setState(() {
image = Image.memory(list);
});
} catch (exception) {
print(exception);
}
}
You can not use Asset Image for images fetched from Network.
Once you get response from your api. Store the url of the image in a String variable. Usually images from API are stored in a web service.
When you have the url of the image just use NetworkImage widget, example:
SizedBox(
width: 75,
height: 75,
child: userImgUrl.isEmpty
? const CircleAvatar(
child: Text('Avatar'))
: CircleAvatar(
radius: 30,
backgroundImage: NetworkImage(
userImgUrl),
backgroundColor: Colors.transparent),)
Think userImgUrl is the String that holds the url for the image that can be found on the internet. If image is empty just show a text inside circle avatar. If image is available from API, then show the image inside NetworkImage()
I am using the following code to pick an image from user's gallery.
Future getImageFromGallery(BuildContext context) async {
await ImagePicker.platform()
.pickImage(source: ImageSource.gallery)
.then((image) {
if (image != null) {
_cropImage(image, context);
}
});
}
I am getting the following warning.
The member 'platform' can only be used within 'package:image_picker/image_picker.dart' or a test.
I'm not sure what the warning means. I tried looking it up but couldn't figure out the solution to resolve this warning.
Try below code hope its help to you
Declare File type form dart.io package
File? imagePicked;
Create Function for pick up the image
void gallaryImage() async {
final picker = ImagePicker();
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
);
final pickedImageFile = File(pickedImage!.path);
setState(() {
imagePicked = pickedImageFile;
});
}
Create your Widget
TextButton(
onPressed: gallaryImage,
child: Text(
'Gallery',
style: TextStyle(
color: Colors.black,
),
),
),
You can just change the code
ImagePicker.platform().pickImage(...)
to
ImagePicker().pickImage(...)
so
Future getImageFromGallery(BuildContext context) async {
await ImagePicker()
.pickImage(source: ImageSource.gallery)
.then((image) {
if (image != null) {
_cropImage(image, context);
}
});
}
I am allowing users to grab a profile pic and upload that picture as file to my server, but I'm getting this error when inputting the image via ImagePickerWeb:
<error>:<getObject: Unexpected error from chrome devtools:>
I don't know if it's my browser or me, but this is what I'm trying:
Future<void> getMultipleImageInfos() async {
var imageFile =
await ImagePickerWeb.getImage(outputType: ImageType.file);
print(imageFile);
if (imageFile != null) {
setState(() {
currentSelfie = imageFile;
_accDetails['customer_selfie'] = currentSelfie;
});
}
}
Then displaying that photo here:
Image.file(
currentSelfie,
height: screenAwareSize(100, context),
width: screenAwareSize(100, context),
fit: BoxFit.fill,
)
I want to display a profile picture of the user when they log in. I am using the image URL stored in firestore database.
I want to keep the image in the app until logout. Every time I start the app, Image is called from that URL but I want to store it. I am new to flutter and have no clue to achieve this task.
Future<void> _getImage(ImageSource source) async {
var image = await ImagePicker.pickImage(source: source);
if (image != null) {
setState(() {
_cropImage(image);
});
}
Navigator.pop(context);
}
// Crop fetched image
_cropImage(File image) async {
File cropped = await ImageCropper.cropImage(
sourcePath: image.path,
aspectRatio: CropAspectRatio(ratioY: 1.0, ratioX: 1.0));
if (cropped != null) {
setState(() {
_imageFile = cropped;
uploadFile();
});
}
}
// Upload image file to firestrore Storage and get image URL
Future uploadFile() async {
StorageReference storageReference = FirebaseStorage.instance
.ref()
.child('${Path.basename(_imageFile.path)}}');
StorageUploadTask uploadTask = storageReference.putFile(_imageFile);
var downUrl = await (await uploadTask.onComplete).ref.getDownloadURL();
var url = downUrl.toString();
await uploadTask.onComplete;
setState(() {
imageUrl = url.toString();
});
// Show message on successful image upload
AppUtils.showToast('Picture Uploaded', green, white);
// Updating database with Image URL
Firestore.instance
.collection('account')
.document(widget.user)
.updateData({"url": imageUrl});
}
// Display Image
ClipRRect(
borderRadius: BorderRadius.circular(200.0),
clipBehavior: Clip.hardEdge,
child: Container(
height: 200,
width: 200,
child: widget.photoUrl == null
? Image(
image: NetworkImage(
'https://cdn1.iconfinder.com/data/icons/technology-devices-2/100/Profile-512.png'),
fit: BoxFit.fill,
)
: Image(
image: NetworkImage(widget.photoUrl),
fit: BoxFit.fill,
))),
What you need is a proper State Management throughout your app.
You can check the Provider Package to get started.
You can find more information about State Management here and here