I'm newbie in "flutter" and I have question.
It's possible to make copy of image and save it in device ?
File image;
picker() async {
print('Picker is called');
File img = await p.ImagePicker.pickImage(source: p.ImageSource.gallery);
if (img != null) {
image = img;
setState(() {});
}
}
save() async {
print('Save is called');
final Directory path = await image.parent;
setState(() {});
}
I have my image and I can get path of directory. But how to save this image in this directory but with another name ?
Let's say my picture is called x.jpg and I want to have the same picture saved as y.jpg without delete of x.jpg
Use simple_permissions plugin to get the permission to write to the external storage.
Use path_provider plugin to get the path to the external storage folder
Finally use the image plugin to write the image
sample code
Future<Io.File> saveImage(Io.File file) async {
try {
var dir = await getExternalStorageDirectory();
var testdir =
await new Io.Directory('${dir.path}/testfolder').create(recursive: true);
IM.Image image = IM.decodeImage(file.readAsBytesSync());
return new Io.File(
'${testdir.path}/${DateTime.now().toUtc().toIso8601String()}.png')
..writeAsBytesSync(IM.encodePng(image));
} catch (e) {
print(e);
return null;
}
}
also check the permission
void checkPer() async {
bool checkResult = await SimplePermissions.checkPermission(
Permission.WriteExternalStorage);
if (!checkResult) {
var status = await SimplePermissions.requestPermission(
Permission.WriteExternalStorage);
//print("permission request result is " + resReq.toString());
if (status == PermissionStatus.authorized) {
//saveimage
}
} else {
//saveimage
}
}
namespaces
import 'dart:io' as Io;
import 'package:image/image.dart' as IM;
import 'package:path_provider/path_provider.dart';
import 'package:simple_permissions/simple_permissions.dart';
Related
I'm using Image picker to pick images from Camera to my Flutter App. The issue I'm having is the images are saved automatically in gallery, but I want to save these images to specific paths.
void pickImage(ImageSource source) async {
try {
XFile? file = await ImagePicker().pickImage(source: source);
if (file != null) {
imagePath = file.path;
setState(() {});
}
} catch (e) {}
}
In Flame documentation, Image class just load from asset folder.
bgSprite = Sprite('avatar/avatar-sample.png');
How can I load network images in Flame.
You could do something like this in versions after 1.0.0:
import dart:ui; // This is the package you want the Image class from, there are several
Future<Image> getImage(String path) async {
Completer<ImageInfo> completer = Completer();
var img = new NetworkImage(path);
img.resolve(ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info,bool _){
completer.complete(info);
}));
ImageInfo imageInfo = await completer.future;
return imageInfo.image;
}
and then in your onLoad method, just initiate bgSprite:
#override
Future<void> onLoad() async {
final image = await getImage("your-url.com/sample.png");
bgSprite = Sprite(image);
}
In 0.28.0, which it looks like you are running, you'll just replace the last line with (but I really recommend upgrading to a version after 1.0.0):
bgSprite = Sprite.fromImage(image);
Getting below error while using the latest version of cloud_firestore: ^0.14.0+2 while uploading image on cloud firestore.
Uncaught (in promise) Error: [cloud_firestore/unknown] Invalid argument (dartObject): Could not convert: Instance of '_Uri'
The image gets successfully uploaded in the storage portion but the image link doesn't get updated in cloud firestore db.
Below is the class from where I pick the image and and hit he upload btn to upload the image
class AddNewItemView extends StatefulWidget {
#override
_AddNewItemViewState createState() => _AddNewItemViewState();
}
class _AddNewItemViewState extends State<AddNewItemView> {
MediaInfo _itemPic;
#override
Widget build(BuildContext context) {
return Scaffold(
.....
child: RawMaterialButton(
onPressed: () async {
MediaInfo pickedImg = await ImagePickerWeb.getImageInfo; <---- image_picker_web package
setState(() {
_itemPic = pickedImg;
});
.........
FlatButton(
onPressed: () async {
bool addDataSuccess = await model.addNewItem( _itemPic);
if (addDataSuccess) {
print("Inside addDataSuccess");
} else {
print("Outside addDataSuccess");
}
},
),
.....
);
}
This class is responsible for extracting image uri from uploadImageFile funtion and uploading it in cloud firestore.
Any other info passed alongside pic gets uploaded in cloud firestore, only 'pic' is not uploading
class ItemViewModel extends BaseViewModel {
Future<bool> addNewItem( MediaInfo pic ) async {
Uri _uploadedImgURL = await ConstantFtns()
.uploadImageFile(pic, "ImgPathString", "fileName");
await FirebaseFirestore.instance.collection('item').doc("tempID").set(
{
'pic': _uploadedImgURL,
'otherInfo': 'otherTempInfo'
},
);
}
in below class I get valid imageUri without any error and image gets uploaded in storage portion only problem is that it don't get uploaded in cloud firestore database
import 'package:firebase/firebase.dart' as fb;
import 'package:mime_type/mime_type.dart';
import 'package:path/path.dart' as p;
class ConstantFtns {
Future<Uri> uploadImageFile(
MediaInfo mediaInfo, String ref, String fileName) async {
try {
String mimeType = mime(p.basename(mediaInfo.fileName));
final String extension = extensionFromMime(mimeType);
var metadata = fb.UploadMetadata(
contentType: mimeType,
);
fb.StorageReference storageReference =
fb.storage().ref(ref).child(fileName + ".$extension");
fb.UploadTaskSnapshot uploadTaskSnapshot =
await storageReference.put(mediaInfo.data, metadata).future;
Uri imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
print("download url $imageUri"); <---- IT GETS P[RINTED AND IT SHOWED VALED IMAGE URL STORED IN STORAGE
return imageUri;
} catch (e) {
print("File Upload Error $e");
return null;
}
}
}
Since what you want is simply to store the URL into firestore you don't really need the getDownloadURL() value to be a Uri object, you just need it's string value, being the error you are getting a conversion error, I suggest that you follow what is recommended in this community answer, that way your code will look like this:
String uploadImageFile(
MediaInfo mediaInfo, String ref, String fileName) async {
try {
...
var imageUri = await uploadTaskSnapshot.ref.getDownloadURL() as String;
print("download url $imageUri"); <---- IT GETS P[RINTED AND IT SHOWED VALED IMAGE URL STORED IN STORAGE
return imageUri
} catch (e) {
...
}
}
})
And you also have to change the call in the ItemViewModel class to:
String _uploadedImgURL = await ConstantFtns()
.uploadImageFile(pic, "ImgPathString", "fileName");
I am working on a chat app:
If the user taps on an image, it will show in full size. The following method is called:
Handle_Tapped():
void Handle_Tapped(object sender, System.EventArgs e)
{
try
{
Image image = sender as Image;
string filePath = String.Empty;
filePath = image.Source as FileImageSource;
Eva3Toolkit.CommonUtils.openImage(filePath);
}
catch (Exception ex)
{
throw ex;
}
}
Which calls (depending on the OS):
openImage() in Android:
public void openImage(string filePath)
{
Intent sendIntent = new Intent(Intent.ActionView);
sendIntent.SetDataAndType(Android.Net.Uri.Parse("file:" + filePath), "image/*");
Forms.Context.StartActivity(Intent.CreateChooser(sendIntent, "Bild öffnen..."));
}
openImage() in iOS:
public void openImage(string filePath)
{
var firstController = ((UIApplicationDelegate)(UIApplication.SharedApplication.Delegate)).Window.RootViewController.ChildViewControllers[0].ChildViewControllers[1].ChildViewControllers[0];
var navcontroller = firstController as UINavigationController;
var docIC = UIDocumentInteractionController.FromUrl(new NSUrl(filePath, true));
docIC.Delegate = new DocInteractionC(navcontroller);
docIC.PresentPreview(true);
}
Now I want to create a method openImage() in UWP, but I don't know know. I know that I will most likely have to work with the image as a StorageFile instead of the path because only a StorageFile grants me permission to open the image.
Is there a way to open the image in full size in UWP? I highly prefer to not create a new view for this.
A Launcher can open a file with the program that is assigned to the file:
public async void openImageAsync(string filePath)
{
StorageFile storageFile = await StorageFile.GetFileFromPathAsync(filePath);
await Launcher.LaunchFileAsync(storageFile);
}
For my situation it's working that I use filePath because the files are in a local folder.
The output looks like this:
i am uploading my image by using plugins.media but the problem is it redirect to another photoimage page and upload it there.
var profiletap = new TapGestureRecognizer();
profiletap.Tapped += async (s, e) =>
{
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
await DisplayAlert("File Location", file.Path, "OK");
ImageSource im = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
await Navigation.PushModalAsync(new PhotoPage(im));
};
profile.GestureRecognizers.Add(profiletap);
ant here is photopage content
public class PhotoPage : demopage
{
public PhotoPage(ImageSource img)
{
Content = new Image
{
VerticalOptions =LayoutOptions.Start,
HorizontalOptions = LayoutOptions.Start,
Source =img
};
}
}
Instead of doing
await Navigation.PushModalAsync(new PhotoPage(im));
you can do something like
var img = new Image
{
Source =im
};
then add the new img control to the same container as where the "profile" control has already been added (probably some Stacklayout or Grid or some other layout control like that)
Be aware that you are struggling with the most basic concept of building out your app UI, which is a strong indicator you should read some getting started tutorials for xamarin.forms and really understand how the UI is built.