Using Camera.MAUI display an image on the device and save it locally and in Documents

Will Autio 5 Reputation points
2023-12-06T05:59:40.4633333+00:00

I am trying to do in Maui what we were able to do in Xamarin Forms. Using Camera.MAUI I take a picture and display it with an Image. If that is all I do, it works as expected.

But wait - there's more. I also need to write the image to where the app has access to it as well as to the Gallery (developing on Android for now but will use the app on iOS as well).

OnButtonClicked (i.e. take a picture) there is the following code behind:

        myImage.Source = cameraView.GetSnapShot                 (Camera.MAUI.ImageFormat.JPEG);
        imageBorder.IsVisible = true; // show a border around myImage
// also, if I stop here, myImage has a nice picture in it.
// but if I continue with the following code it goes sideways...

        // somewhere I found this code for converting an ImageSource to a stream
        using Stream stream = await ((StreamImageSource)myImage.Source).
                                Stream(CancellationToken.None);

        // and then I copy the stream to a byteArray for future use
        byte[] bytes = new byte[stream.Length];
        stream.Write(bytes, 0, bytes.Length);

        // but something did not look right with the byteArray. It seemed // filled with zeroes. And the Image displayed was all Black.
// And sure enough, the following loop confirmed that every byte was 0
        long l = stream.Length;
        int j = 0;
        for (int i = 0; i < stream.Length; i++)
        {
            if (bytes[i] == 0)
            {
                j++;
            }
        }
        Debug.WriteLine("len=" + l + " j=" + j);

So, what am I doing wrong? And how can I finish this off by writing the Image to those two aforementioned places?
Thanks!
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,223 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 72,171 Reputation points Microsoft Vendor
    2023-12-07T08:30:53.7133333+00:00

    Hello,

    there's more. I also need to write the image to where the app has access to it as well as to the Gallery (developing on Android for now but will use the app on iOS as well).

    For this thread, lets focus on the android platform. For iOS issue, please open a new thread in this site.

    As note:Avoid posting multiple questions in a single thread

    Firstly, you cannot get Stream by using Stream stream = await ((StreamImageSource)myImage.Source). Stream(CancellationToken.None);, this line does not guarantee that the images are in an app-readable format or imagesource type.

    we can get stream by Stream stream = await cameraView.TakePhotoAsync(); directly and you can use ContentResolver to save this image to the gallery like following code.

     private async void Button_Clicked(object sender, EventArgs e)
        {
            Stream stream = await cameraView.TakePhotoAsync();
    #if ANDROID
           try
              {      
                ContentResolver resolver = Microsoft.Maui.ApplicationModel.Platform.CurrentActivity.ContentResolver;
                ContentValues contentValues = new ContentValues();
                contentValues.Put(MediaStore.Images.ImageColumns.DisplayName, "test.png");
                contentValues.Put(MediaStore.Images.ImageColumns.DateTaken, DateTime.UtcNow.ToUniversalTime().ToString());
                contentValues.Put(MediaStore.Images.ImageColumns.DateAdded, DateTime.UtcNow.ToUniversalTime().ToString());
                contentValues.Put(MediaStore.Images.ImageColumns.Size, stream.Length);
                contentValues.Put(MediaStore.Images.ImageColumns.MimeType, "image/png");
                contentValues.Put(MediaStore.Images.ImageColumns.RelativePath, Android.OS.Environment.DirectoryPictures);
                Android.Net.Uri uri = resolver.Insert(MediaStore.Images.Media.ExternalContentUri, contentValues);
                Stream outputStream = resolver.OpenOutputStream(uri);
                await stream.CopyToAsync(outputStream);
              }
              catch (Exception e1)
              {
                  Console.WriteLine(e1.ToString());  
                  throw;
              }
            
    #endif
    
    }
    

    By the way, please do not forget to add following used namespaces.

    #if ANDROID
    using Android.Content;
    using Android.Provider;
    #endif
    

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.