SvgPicture can't be assigned to ImageProvider - flutter

I'm trying to use svg image as background in Container and I use this package "flutter_svg" I can't found a Provider method to set it in decoration
Container(
margin: EdgeInsets.symmetric(horizontal: 5),
width: 60,
height: 20,
decoration: BoxDecoration(
color: currentColor.medium,
borderRadius: BorderRadius.circular(4),
image: DecorationImage(
image: SvgPicture.asset('assets/images/home.png'),
),
),
);
The argument type 'SvgPicture' can't be assigned to the parameter type 'ImageProvider'.dart(argument_type_not_assignable)
so I don't know how to use svg as ImageProvider here , any idea

There are two options:
First one, write a function for that, as commented in flutter_svg package at here:
final String rawSvg = '''<svg viewBox="...">...</svg>''';
final DrawableRoot svgRoot = await svg.fromSvgString(rawSvg, rawSvg);
final Picture picture = svgRoot.toPicture();
final Image image = await picture.toImage(width, height);
return RawImage(image, 1.0);
And second one, use another package on top of svg_flutter package:
import 'package:flutter_svg_provider/flutter_svg_provider.dart';
Image(
width: 32,
height: 32,
image: Svg('assets/my_icon.svg'),
)

You should add to your pubspec.yaml, flutter_svg_provider: ^1.0.0 instead of flutter_svg: ^1.0.0

Flutter developers have created one library you can find here
https://www.developerlibs.com/2019/06/flutter-draw-svg-vector-drawables.html

Related

Dislaying Image File in Container Exported From Video

Trying to export a frame from my video file, save it to an image file list, and then display it back when building my list of containers.
setState(() async{
if (result!.files.isNotEmpty) {
for (PlatformFile item in result.files) {
videos.add(File(item.path!));
var duration = Duration(seconds: 1);
File image = await ExportVideoFrame.exportImageBySeconds(File(item.path!), duration, 0);
videoThumbs.add(image);
//tickets[widget.indexEvent].videos[i]
}
} else {}
});
Then later in my page class I am trying to display it back for the user in a child of my container:
Container(
width: 220,
height: 220,
color: colorPrimary,
child: Image.file(
videoThumbs[i],
width: 100,
height: 100,
fit: BoxFit.fill,
),
),
The code doesn't hard fail, and will build the apk, but when in the app, my thumbnail just says:
As you can see from my thumbnail, my list of photos and videos are building, but when it tries to loop through the videos and show a thumb, the array index is empty, I think? I believe I'm reading that error right.
I have seriously been at this for 2 weeks, and I could really use some help.
in this list, Your data is not complete, on 2 last of your data is null.
use this:
child:
videoThumbs[I] == null? const SizedBox():
Image.file(
videoThumbs[i],
width: 100,
height: 100,
fit: BoxFit.fill,
),

How to set Container Background image as Image.file() form XFile source in flutter

I am using this function to get images from the gallery
_getFromGallery() async {
XFile? pickedFileGal = await ImagePicker().pickImage(
source: ImageSource.gallery,
maxWidth: 1800,
maxHeight: 1800,
);
if (pickedFileGal != null) {
XFile imageFileGal = XFile(pickedFileGal.path);
setState(() {
_imageFile = imageFileGal;
});
}
}
late XFile _imageFile;
I need to set the image to the container background, the container has a child column. So I need to set it in BoxDecoration, but I have the image in XFile the container BoxDecoration image does not take Image.file(). So how can I achieve that? Please guide me
Container(
decoration: BoxDecoration(
image: Image.file(_imageFile), //Error
),
padding: const EdgeInsets.only(top: 20),
color: Colors.white,
margin: const EdgeInsets.only(
bottom: 15,
),
child: Column(
children: []))
First the image here needs to be a DecorationImage which then takes ImageProvider<Object>.
Knowing this , the correct way to use this is as follows
Container(decoration: BoxDecoration(
image: DecorationImage(image: Image.file('file').image)
),),
Xfile to file
Xfile pickedFile;
Image.file(File(pickedFile.path))

Show picture from assets or from files Flutter

I want to show a picture inside a CircleAvatar, if the user never inserted a picture before then the default picture "empty_profile.png" will appear, otherwise if the user already inserted a picture from gallery or camera then the last one will be shown.
This is the code :
File _file = null;
File variable declared at the beginning.
Future<void> changeImage() async { //This will change the picture
File tmp = await imgFromGallery();
setState(() {
_file = tmp;
});
return;
}
The function above will change _file value to the file picked from gallery.
Widget myAvatar() {
return GestureDetector(
onTap: null,
child: CircleAvatar(
radius: 55,
backgroundColor: Color(0xffFDCF09),
child: CircleAvatar(
radius: 50,
child: Container(
child: _file == null
? AssetImage("empty_profile.png")
: FileImage(_file),
),
),
),
);
}
Finally if file is still null then the asset image is loaded, otherwise if a new picture is choosen then FileImage(_file) will show the picked image.
I have a lots of error because I don't know very well how to handle files, their paths and show images...Can you explain me how I should do?
To include static images in your Flutter project, place them inside the "assets/images" folder. Then, make sure to add this folder to your pubspec.yml:
flutter:
assets:
- assets/images/
Next, you may have errors related to trying to render an AssetImage inside a CircleAvatar. To render the file as an Image widget instead, use Image.asset(<path>). Your example could be written as:
Widget myAvatar() {
return GestureDetector(
onTap: null,
child: CircleAvatar(
radius: 55,
backgroundColor: Color(0xffFDCF09),
child: _file == null
? Image.asset("assets/images/empty_profile.png")
: _file
),
);
}
Finally, a great resource for user-selected images is the image_picker library: https://pub.dev/packages/image_picker. For example, a "Select from Gallery" button could invoke the following code, which allows the user to crop the image and saves it as an Image widget:
PickedFile image = await picker.getImage(
source: ImageSource.gallery, // to select from camera, use ImageSource.camera
maxHeight: 1024,
maxWidth: 1024,
imageQuality: 50
);
try {
File croppedImage = await ImageCropper.cropImage( // use platform-native image cropping
sourcePath: image.path,
cropStyle: CropStyle.circle,
maxWidth: 512,
maxHeight: 512
);
setState(() { // refresh state to render new profile image
_file = Image.file(croppedImage)
})
} catch (err) {
print(err)
}
You can use CachedNetworkImage PlugIn - Update other details as per your need. This code show Network Images, if not available will show Assets Image.
new Container(
width: 140.0,
height: 140.0,
child: ClipOval(
child: CachedNetworkImage(
imageUrl: _profile == null ? "" : Api.baseURL + _profile,
placeholder: (context, url) =>
Center(child: CircularProgressIndicator()),
errorWidget: (context, url, error) => Image.asset(
"img/user.png",
fit: BoxFit.cover,
height: 140.0,
width: 140.0,
),
fit: BoxFit.cover,
height: 140.0,
width: 140.0,
),
),
),

onError method of DecorationImage() in Flutter

Code works fine but because of my unreliable internet connection I am faced with an issue of NetworkImage.load ( See error image below )
Container(
width: 60,
height: 80,
decoration: BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.all(Radius.circular(7.0))
image: DecorationImage(
image: NetworkImage(trend['imageUrl']),
onError: <how we can handle this?>,
fit: BoxFit.cover
),
),
);
I hope this issue can be fixed by handling it on onError method (Correct me if I'm wrong). But I can't figure it out how to do that.
Error:
First of all lets say you intialize NetworkImage inside your class. like:
var imgVariable = NetworkImage(trend['imageUrl']);
Then, load your network image. If, error occurs then we will load from our assets to let user know that we could not load network image.
Container(
width: 60,
height: 80,
decoration: BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.all(Radius.circular(7.0))
image: DecorationImage(
image: imgVariable,
onError: (errDetails){
setState(){
imgVariable = AssetImage('assets/could_not_load_img.jpg');
};
},
fit: BoxFit.cover
),
),
);
Here, assets/could_not_load_img.jpg is image that is imformative sthg.
*Note: This may not seem to work with errors, but this can be a way I came up with. There are plugins like cached_network_image to work beautifully on network images.
The accepted solution by Biplove doesn't seem to work anymore, at least I couldn't solve the resulting cast error when replacing the NetworkImage with an AssetImage. But a similar way would be:
class _YourClassState extends State<YourClass> {
bool networkError = false;
NetworkImage backgroundImage = const NetworkImage(
'youUrl');
AssetImage backgroundImageFallback = AssetImage('assets/img/....jpg');
...
decoration: !networkError ? DecorationImage(
fit: BoxFit.fill,
onError: (Object e, StackTrace? stackTrace) {
log("Could not load the network image, showing fallback instead. Error: ${e.toString()}");
if (stackTrace != null) {
log(stackTrace.toString());
}
setState(() {
networkError = true;
});
},
image: backgroundImage) :
DecorationImage(
fit: BoxFit.fill,
image: backgroundImageFallback)
}
so, onError in flutter basically takes a return type of function
it takes some error that may generate during the loading/fetching of the response image URL as the parameter Error that is generated during call and a report that provides information about program subroutines that can be found in the debug console as well
onError:(error, stackTrace) => AssetImage('assets/could_not_load_img.jpg'),
or you can check these
[click]https://github.com/flutter/flutter/issues/78925#issuecomment-806553363
[click]https://github.com/flutter/flutter/issues/78925

type 'FutureBuilder<File>' is not a subtype of type 'ImageProvider<dynamic>' - Image Picker problem

I need to add an image in a Container. The image is coming from IMAGE PICKER.
Im getting the error:
type 'FutureBuilder<File>' is not a subtype of type 'ImageProvider<dynamic>'
Here's the original code:
Container( //<-- HEADER CONTAINER
height: kHeaderHeight,
width: kHeaderWidth,
decoration:
BoxDecoration(
image: DecorationImage(
image:
_imageFileForHeader.path != null?
FutureBuilder(
future: _getLocalFile(_imageFileForHeader.path),
builder: (BuildContext context, AsyncSnapshot<io.File> snapshot)
{
return Image.file(snapshot.data);
}
):
NetworkImage(urlImage + _kHeaderImage), fit: BoxFit.cover,
),
),
I really could do with any help here.
If the user does not select an image from the gallery - then use the image in the URL (urlImage).
I think I'm doing a very standard routine, and I cannot see why its not working.
Thanks
-- I just want to add that I tried also :
return FileImage(snapshot.data)
and this did not work either.
I think I exhausted every permutation possible here.
By the way, here's the _getLocalFile...
Future<io.File> _getLocalFile(String filename) async
{
io.File f = new io.File(filename);
return f;
}
You don't need any future in _getLocalFile as there is no async operations inside. You can just do
return Container( //<-- HEADER CONTAINER
height: kHeaderHeight,
width: kHeaderWidth,
decoration:
BoxDecoration(
image: DecorationImage(
image: _imageFileForHeader?.path != null
? Image.file(File(_imageFileForHeader.path))
: Image.network(urlImage + _kHeaderImage);
),
),
Or Assuming _imageFileForHeader is already a file we could simplify this even more
return Container( //<-- HEADER CONTAINER
height: kHeaderHeight,
width: kHeaderWidth,
decoration:
BoxDecoration(
image: DecorationImage(
image: _imageFileForHeader != null
? Image.file(_imageFileForHeader)
: Image.network(urlImage + _kHeaderImage);
),
),
I think your _getLocalFile function returns the wrong datatype. Maybe if you try the following:
Future<File> _getLocalFile() async{
final ImagePicker _picker = ImagePicker();
PickedFile pickedFile= await _picker.getImage(source: ImageSource.gallery);
File file = File(pickedFile.path);
return file;
}
Futhermore, I donĀ“t belive that you can use a FutureBuilder for the Containers image variable. To display a image inside a Container you can use:
File file;
Container(
decoration: new BoxDecoration(
image: new DecorationImage(
fit: BoxFit.cover,
image: new FileImage(file),
),
),
),
So I think you have to check the file variable for null and if it is null, maybe show a button. If the user presses the button, you can call the async _getLocalFile function and than maybe update with setState to show the image.
Maybe you could also wrap the image around a FutureBuilder:
FutureBuilder<File>(
future: _getLocalFile(),
builder: (BuildContext context, AsyncSnapshot<File> snapshot)
{
if(!snapshot.hasData){
return CircularProgressIndicator();
}else{
return Container(
decoration: new BoxDecoration(
image: new DecorationImage(
fit: BoxFit.cover,
image: new FileImage(snapshot.data),
),
),
);
}
}
);