How to Display Camera Preview in .NET MAUI? - maui

Currently, what I did is to access the camera and use it to take a picture, but this isn't exactly what I want to accomplish.
I want to activate and display front camera preview on my content page, and then take a picture by pressing a button control.
I've searched around and I can't seem to find any solution. In Xamarin, there's CameraView from Xamarin Community Toolkit that can be used for camera stream, but from the looks of it, CameraView hasn't been implemented in .NET MAUI Community Toolkit. Is there any other way to do this? Thank you.

This is the code for the button event
private async void takephoto(object sender, EventArgs e)
{
if (MediaPicker.Default.IsCaptureSupported)
{
FileResult photo = await MediaPicker.Default.CapturePhotoAsync();
if (photo != null)
{
// save the file into local storage
string localFilePath = Path.Combine(FileSystem.CacheDirectory, photo.FileName);
using Stream sourceStream = await photo.OpenReadAsync();
Stream stream = await photo.OpenReadAsync();
using FileStream localFileStream = File.OpenWrite(localFilePath);
await sourceStream.CopyToAsync(localFileStream);
DisplayPhoto.Source = ImageSource.FromStream(() =>
{
return stream;
});
}
}
}

Related

maui: showing picture from gallery not working

Im grabbing a picture from the gallery like described in the docs. that works, I can pick the pictures in my ios gallery and I am getting a full stream:
string localFilePath = System.IO.Path.Combine(FileSystem.CacheDirectory, photo.FileName);
using Stream sourceStream = await photo.OpenReadAsync();
using FileStream localFileStream = File.OpenWrite(localFilePath);
await sourceStream.CopyToAsync(localFileStream);
MainThread.BeginInvokeOnMainThread(() =>
{
img_profilePic.Source = ImageSource.FromStream(() => localFileStream);
img_profilePic.IsVisible = true;
});
But when I try to set the image to the imagesource of my image from xaml, nothing changes in the UI.
If I change the image to a local image however, it updates the UI. So it must be something with the stream.
Anyone got any idea?

Saving the input image from Face detection as a file? [Flutter + Google ML Kit Face Detection]

is it possible to save the processed image as a File?
Here is what I'm trying to do, our app have a KYC (Know your customer) and we implemented the
face detection to make the users do several poses. What I want is to save them as an image file and upload it on the database
Example Scenario:
App ask the user to smile > The user smiled > save the image.
Here is what I have right now:
Where the app checks if the user smiled
if (faces.isNotEmpty) {
if (inputImage.inputImageData?.size != null &&
inputImage.inputImageData?.imageRotation != null) {
if (faces[0].smilingProbability! > 0.85) {
await _getImg();
}
}
}
Then I call a Function to stop image stream then take a picture (this works but on some physical device it crashes) but if I dont stop the image stream then called the takePicture() right-away it just crashes all the time.
_getImg() async {
setState(() {
globalBusy = true;
});
await _controller.stopImageStream();
var img = await _controller.takePicture();
VerificationVarHandler.livelinesImgsPaths.add(img.path);
}
As you can see it's not the best way at least for me I think, so maybe I can use the
inputImage from the _processCameraImage() because it has a byte? then I can pass that bytes to a decoder and save it locally when I trigger a function?
Or maybe better yet there is more elegant way of achieving this?
You can check out this gfg article - https://www.geeksforgeeks.org/face-detection-in-flutter-using-firebase-ml-kit/
Learn flutter in easiest way - https://auth.geeksforgeeks.org/user/ms471841/articles

Is there a way to detect available applications to pick image like gallery , amazon photos , google photos ... using flutter image picker

I want to create an image picker like android native that detect all available applications to pick image using flutter image picker.
To be more specific I want to display the available image applications.
Hey Don't know about image_picker, but file_picker works for me as below
Future getFromGallery() async {
FilePickerResult? result =
await FilePicker.platform.pickFiles(type: FileType.image);
if (result != null) {
setState(() {
pickedImage = File(result.files.single.path!);
});
}
}

Post two images on Facebook with UWP Community Toolkit

Is there a way to post two images in a single post with UWP Community Toolkit?.
I think it is possible, you can check the official sample app of UWP Community Toolkit.
It has encapsulated the twitter apis in its service. And according to the Twitter developer documentation: Uploading Media, it is supported to upload maximum 4 photos in a tweet.
In a word, you can open the project of this sample app, and find SamplePages -> Twitter Service -> TwitterPage.xaml.cs, finally find the SharePictureButton_OnClick event and override the original code:
StorageFile picture = await openPicker.PickSingleFileAsync();
if (picture != null)
{
using (var stream = await picture.OpenReadAsync())
{
await TwitterService.Instance.TweetStatusAsync(TweetText.Text, stream);
}
}
to:
var pictures = await openPicker.PickMultipleFilesAsync();
int num = pictures.Count;
List<IRandomAccessStream> streams = new List<IRandomAccessStream>();
foreach (var picture in pictures)
{
var stream = await picture.OpenReadAsync();
streams.Add(stream);
}
await TwitterService.Instance.TweetStatusAsync(TweetText.Text, streams.ToArray());

Xamarin.Forms Taking picture with Plugin.Media not working

I'm using the Plugin.Media from #JamesMontemagno version 2.4.0-beta (which fixes picture orientation), it's working on Adroind 4.1.2 (Jelly Bean) and Marshmallow, but NOT on my Galaxy S5 Neo with Android version 5.1.1.
Basically when I take a picture it never returns back on the page from where I started the process; always returns back to the initial home page.
On devices where it works, when I take a picture, I see that first of all the application fires OnSleep, then after taking the picture fires OnResume.
On my device where is NOT working it fires OnSleep and after taking the picture doesn't fire OnResume, it fires the initialization page and then OnStart.
For this reason it doesn't open the page where I was when taking the picture.
What should I do to make sure it fires OnResume returning to the correct page and not OnStart which returns on initial fome page ?
In addition, when I take a picture it takes almost 30 seconds to get back to the code after awaiting TakePhotoAsync process, and it's too slow!
Following my code:
MyTapGestureRecognizerEditPicture.Tapped += async (sender, e) =>
{
//Display action sheet
String MyActionResult = await DisplayActionSheet(AppLocalization.UserInterface.EditImage,
AppLocalization.UserInterface.Cancel,
AppLocalization.UserInterface.Delete,
AppLocalization.UserInterface.TakePhoto,
AppLocalization.UserInterface.PickPhoto);
//Execute action result
if (MyActionResult == AppLocalization.UserInterface.TakePhoto)
{
//-----------------------------------------------------------------------------------------------------------------------------------------------
//Take photo
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert(AppLocalization.UserInterface.Alert, AppLocalization.UserInterface.NoCameraAvailable, AppLocalization.UserInterface.Ok);
}
else
{
var MyPhotoFile = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
Directory = "MyApp",
Name = "MyAppProfile.jpg",
SaveToAlbum = true,
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Small
});
if (MyPhotoFile != null)
{
//Render image
MyProfilePicture.Source = ImageSource.FromFile(MyPhotoFile.Path);
//Save image on database
MemoryStream MyMemoryStream = new MemoryStream();
MyPhotoFile.GetStream().CopyTo(MyMemoryStream);
byte[] MyArrBytePicture = MyMemoryStream.ToArray();
await SaveProfilePicture(MyArrBytePicture);
MyPhotoFile.Dispose();
MyMemoryStream.Dispose();
}
}
}
if (MyActionResult == AppLocalization.UserInterface.PickPhoto)
{
//-----------------------------------------------------------------------------------------------------------------------------------------------
//Pick photo
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert(AppLocalization.UserInterface.Alert, AppLocalization.UserInterface.PermissionNotGranted, AppLocalization.UserInterface.Ok);
}
else
{
var MyPhotoFile = await CrossMedia.Current.PickPhotoAsync();
if (MyPhotoFile != null)
{
//Render image
MyProfilePicture.Source = ImageSource.FromFile(MyPhotoFile.Path);
//Save image on database
MemoryStream MyMemoryStream = new MemoryStream();
MyPhotoFile.GetStream().CopyTo(MyMemoryStream);
byte[] MyArrBytePicture = MyMemoryStream.ToArray();
await SaveProfilePicture(MyArrBytePicture);
MyPhotoFile.Dispose();
MyMemoryStream.Dispose();
}
}
}
};
Please help!! We need to deploy this app but we cannot do it with this problem.
Thank you in advance!
It is perfectly normal to have the Android OS terminate and restart an Activity. As you are seeing, your app's Activity it will be automatically restarted when the camera app exits and the OS returns control to your app. The odds are it just needed more memory in order to take that photo with the Neo's 16MP camera, you can watch the logcat output to confirm that.
Restarted – It is possible for an activity that is anywhere from paused to stopped in the lifecycle to be removed from memory by Android. If the user navigates back to the activity it must be restarted, restored to its previously saved state, and then displayed to the user.
What to do:
So on the Xamarin.Forms OnStart lifecycle method you need to restore your application to a valid running state (initializing variables, preforming any bindings, etc...).
Plug code:
The Android platform code for the TakePhotoAsync method looks fine to me, but remember that the memory for that image that is passed back via the Task will be doubled as it is marshaled from the ART VM back the Mono VM. Calling GC.Collect() as soon as possible after the return will help (but your Activity is restarting anyway...)
public async Task<MediaFile> TakePhotoAsync(StoreCameraMediaOptions options)
{
~~~
var media = await TakeMediaAsync("image/*", MediaStore.ActionImageCapture, options);
In turn calls:
this.context.StartActivity(CreateMediaIntent(id, type, action, options));
Not much less you can really do within the Android OS to popup the Camera.
In addition, when I take a picture it takes almost 30 seconds to get back to the code after awaiting TakePhotoAsync process, and it's too slow!
Is that on your Neo? Or all devices?
I would call that very suspect (ie. a bug) as even flushing all the Java memory after the native Camera Intent/Activity and the restart time for your app's Activity should not take 30 seconds on a oct-core 1.6 GHz Cortex... but I do not have your device, app and code in front of me....