I'm trying to bumble my way through making a cross platform camera app in .Net MAUI.
I've achieved everything I want so far, but the last step is having the app resize the image before saving.
I'm trying to understand how to use Microsoft.Maui.Graphics but there's just enough missing from my understanding of C# to have it elude me.
https://learn.microsoft.com/en-us/dotnet/maui/user-interface/graphics/images
This is what I have to capture and save the image. I presume I need to use Downsize on the captured stream before saving, but it doesn't seem to matter what I try, I just get errors.
async void Button_Clicked(object sender, EventArgs e)
{
var result = await MediaPicker.CapturePhotoAsync();
setAsset();
if (result != null)
{
using var stream = await result.OpenReadAsync();
using var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
stream.Position = 0;
memoryStream.Position = 0;
var fName = projID.Text + "-" + assID.Text + "-" + wDetail.Text + ".jpg";
#if WINDOWS
//await System.IO.File.WriteAllBytesAsync(@"C:\Users\dentk\Desktop\VenPhotos\" + fName, memoryStream.ToArray);
#elif ANDROID
var context = Platform.CurrentActivity;
if (OperatingSystem.IsAndroidVersionAtLeast(29))
{
Android.Content.ContentResolver resolver = context.ContentResolver;
Android.Content.ContentValues contentValues = new();
contentValues.Put(Android.Provider.MediaStore.IMediaColumns.DisplayName, fName);
contentValues.Put(Android.Provider.MediaStore.IMediaColumns.MimeType, "image/jpg");
contentValues.Put(Android.Provider.MediaStore.IMediaColumns.RelativePath, "DCIM/" + "test");
Android.Net.Uri imageUri = resolver.Insert(Android.Provider.MediaStore.Images.Media.ExternalContentUri, contentValues);
var os = resolver.OpenOutputStream(imageUri);
Android.Graphics.BitmapFactory.Options options = new();
options.InJustDecodeBounds = true;
var bitmap = Android.Graphics.BitmapFactory.DecodeStream(stream);
bitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Jpeg, 60, os);
os.Flush();
os.Close();
}
else
{
Java.IO.File storagePath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim);
string pathIO = System.IO.Path.Combine(storagePath.ToString(), fName);
System.IO.File.WriteAllBytes(pathIO, memoryStream.ToArray());
var mediaScanIntent = new Android.Content.Intent(Android.Content.Intent.ActionMediaScannerScanFile);
mediaScanIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(pathIO)));
context.SendBroadcast(mediaScanIntent);
}
#elif IOS || MACCATALYST
var image = new UIKit.UIImage(Foundation.NSData.FromArray(memoryStream.ToArray()));
image.SaveToPhotosAlbum((image, error) =>
{
});
#endif
fileSaveLoc.Text = fName;
await GetCurrentLocation();
if (latlong != null)
{
double lat = Math.Round(latlong.Latitude, 6);
double lng = Math.Round(latlong.Longitude, 6);
latlngRes.Text = lat.ToString() + " : " + lng.ToString();
}
else
{
latlngRes.Text = "Unable to Retreive Location";
}
}
}
This seems so straightforward, but I just cannot get it integrated into my existing code:
using Microsoft.Maui.Graphics.Platform;
...
IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
image = PlatformImage.FromStream(stream);
}
// Save image to a memory stream
if (image != null)
{
IImage newImage = image.Downsize(150, true);
using (MemoryStream memStream = new MemoryStream())
{
newImage.Save(memStream);
}
}
Any help would be greatly appreciated.
I'm guessing getting the existing memoryStream into an IImage is the key, but how do I do that?
......
stream.CopyTo(memoryStream);
stream.Position = 0;
memoryStream.Position = 0;
IImage image;
// something here to get memoryStream into image
if (image != null)
{
IImage newImage = image.Downsize(150, true);
using (MemoryStream memStream = new MemoryStream())
{
newImage.Save(memStream);
}
}
// something to continue and save memStream to continue on and save into the phones gallery
......