How to save ImageSource to jpg in maui?

Viewed 30

i want to save ImageSource result from screen shoot in maui. i found error in casting :

System.InvalidCastException: 'Specified cast is not valid.'

Main:

using ScreenShot.ViewModel;
    namespace ScreenShot;
    public partial class MainPage : ContentPage
    {
        private readonly MainViewModel viewModel;
        public MainPage(MainViewModel viewModel)
        {
            InitializeComponent();
            BindingContext = this.viewModel = viewModel;
        }   
    }

and xaml code:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:ScreenShot.ViewModel"
             x:DataType="vm:MainViewModel"
             x:Class="ScreenShot.MainPage">
    <ScrollView>
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">
            <Image
                Source="dotnet_bot.png"
                SemanticProperties.Description="Cute dot net bot waving hi to you!"
                HeightRequest="200"
                HorizontalOptions="Center" />            
            <Button HorizontalOptions="Center" Text="Take screen shot" Command="{Binding TakeScreenShotCommand}" />            
            <Image Source="{Binding ScreenGrab}" />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

Service Class:

namespace ScreenShot
{
    public class AndroidService : MyService
    {
        public async void Convert(string filename, ImageSource img)
        {
            var handler = new FileImageSourceHandler();
            Bitmap pic = await handler.LoadImageAsync(img, Android.App.Application.Context);//here the error (Casting Error)

            var savedImageFilename = Path.Combine("/storage/emulated/0/DCIM/CAMERA", filename);
            Stream outputStream;
            using (outputStream = new FileStream(savedImageFilename, FileMode.Create))
            {
                bool success;
                if (Path.GetExtension(filename).ToLower() == ".png")
                {
                    success = await pic.CompressAsync(Bitmap.CompressFormat.Png, 100, outputStream);
                }
                else
                    success = await pic.CompressAsync(Bitmap.CompressFormat.Jpeg, 100, outputStream);
            }
        }
    }
}

View Model:

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace ScreenShot.ViewModel;

public partial class MainViewModel : ObservableObject
{
    private readonly MyService myService;
    
    public MainViewModel(MyService myService)
    {
        this.myService = myService;
    }

    [ObservableProperty]
    ImageSource _screenGrab;

    [RelayCommand]
    async Task TakeScreenShot()
    {        
        ScreenGrab = await TakeScreenshotAsync();
        myService.Convert("abcd", ScreenGrab);
    }
        
    private async Task<ImageSource> TakeScreenshotAsync()
    {
        if (Screenshot.Default.IsCaptureSupported)
        {
            IScreenshotResult screen = await Screenshot.Default.CaptureAsync();

            Stream stream = await screen.OpenReadAsync();

            return ImageSource.FromStream(() => stream);
        }
        return null;
    }    
}

Interface:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ScreenShot
{
    public interface MyService
    {
        public void Convert(string filename, ImageSource img);
    }
}

Services builder:

using ScreenShot.ViewModel;

namespace ScreenShot;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            });

        builder.Services.AddSingleton<MainViewModel>();
        builder.Services.AddSingleton<MainPage>();
        builder.Services.AddSingleton<MyService, AndroidService>();

        return builder.Build();
    }
}

the error result in Service Class file mention above due to ivalid casting is there a way to solve problem?

0 Answers
Related