Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG from URL example on Maui #51

Closed
Tricky0815 opened this issue Feb 2, 2023 · 5 comments · Fixed by #89
Closed

SVG from URL example on Maui #51

Tricky0815 opened this issue Feb 2, 2023 · 5 comments · Fixed by #89
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@Tricky0815
Copy link

Is there any possibility to get an example of showing svgs from remote urls?
The samples only provides a constant "SvgUrl" which is never used...

@FreakyAli
Copy link
Owner

Hi, @Tricky0815 As of right now the only images that you can show are embedded, I do have a long-term plan though to add a URL-based download mechanism it's just that I did not get the time to do so, Also I don't see myself getting the time to do this for a couple of weeks, Maui is still quite new and even I am getting used to it so this might take some time. A lot of existing XF things are broken in Maui which is also one of the reasons why I don't feel like putting too much time into this.
If you might have noticed there is already a URL-based downloading code setup available if you would like to make this change for yourself we would love to get a PR, if not this might take some time for now.

@FreakyAli FreakyAli added enhancement New feature or request help wanted Extra attention is needed labels Feb 2, 2023
@FreakyAli
Copy link
Owner

As a workaround, you could download the SVG as a base64 and then use the control, something like this https://stackoverflow.com/a/57778005/7462031 but make sure you are handling threads properly to avoid Memory leaks :)

@Tricky0815
Copy link
Author

Tricky0815 commented Feb 8, 2023

Have done some research and came to the following working solution (could take some optimizations for sure), but should represent the idea via MVVM - its also a kind of a workaround, means - downloading it, converting it to an PNG and bind its imagesource from the file. Hope this helps someone...
View:

<?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"
             x:Class="TestApp.MainPage"
             xmlns:local="clr-namespace:TestApp">
    <ContentPage.BindingContext>
        <local:MainViewModel></local:MainViewModel>
    </ContentPage.BindingContext>
    <ScrollView>
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">
            <Image
                Source="{Binding ImageS}"
               
                HeightRequest="200" WidthRequest="200" Background="Transparent" Aspect="AspectFit"
                HorizontalOptions="Center" />
        </VerticalStackLayout>
</ScrollView>
<ContentPage>

Code-Behind - MainPage.cs:


public partial class MainPage : ContentPage
{
	int count = 0;
    public ImageSource SvgImageSource
	{
		get; set;
	}

    public MainPage()
	{
		InitializeComponent();
	
	}

	private void OnCounterClicked(object sender, EventArgs e)
	{
		count++;

		if (count == 1)
			CounterBtn.Text = $"Clicked {count} time";
		else
			CounterBtn.Text = $"Clicked {count} times";

		SemanticScreenReader.Announce(CounterBtn.Text);
	}


}

MainViewModel:

using SkiaSharp;
using System.ComponentModel;
using System.Runtime.CompilerServices;


namespace TestApp
{
    internal class MainViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));


        private ImageSource _imageS;
        public ImageSource ImageS
        {
            get => _imageS;
            set { _imageS = value; OnPropertyChanged(); }
        }

        public MainViewModel()
        {
            //SVG Load and display on Viewmodel-Init
            DownloadSVG(@"https://cdn.onlinewebfonts.com/svg/download_535318.svg");
        }

        //Async Filesystem-Check-Wrapper
        private async Task<bool> CheckFileExistenceAsync(string filePath)
        {
            return await Task.Run(() => File.Exists(filePath));
        }
        public async void DownloadSVG(string url)
        {
            try
            {
                // Save to Directory-Check
                string PathOfFile = Path.Combine(FileSystem.CacheDirectory, "Testimage.png");
                // File already downloaded --> just return the existing ImageSource from File
                if (await CheckFileExistenceAsync(PathOfFile))
                {
                    ImageS = ImageSource.FromFile(PathOfFile);
                    return;
                }
                //else try to download...
                using (var client = new HttpClient())
                {
                    var response = await client.GetAsync(url);

                    // Client reponse --> SVG-File exists
                    if (response.IsSuccessStatusCode)
                    {


                        var imageBytes = await response.Content.ReadAsByteArrayAsync();

                        using (var stream = new MemoryStream(imageBytes))
                        {
                            var svg = new SkiaSharp.Extended.Svg.SKSvg();
                            svg.Load(stream);


                            // Save 2 canvas
                            var image = new SkiaSharp.SKBitmap((int)svg.CanvasSize.Width, (int)svg.CanvasSize.Height);
                            using (var canvas = new SkiaSharp.SKCanvas(image))
                            {
                                canvas.DrawPicture(svg.Picture);
                            }


                            SKImage img = SKImage.FromBitmap(image);

                            //Create PNG from SKBitmap
                            SKData encodedData = img.Encode(SKEncodedImageFormat.Png, 100);
                            string imgPath = PathOfFile;
                            // Open PNG
                            using (var bitmapImageStream = File.Open(imgPath, FileMode.Create, FileAccess.Write, FileShare.None))
                            {
                               
                                encodedData.SaveTo(bitmapImageStream);

                                // Cleanup
                                await bitmapImageStream.FlushAsync();
                                await bitmapImageStream.DisposeAsync();

                            }
                            // Return ImageSource from File
                            ImageS = ImageSource.FromFile(imgPath);


                        }
                    }


                }
            }
            // handle Exceptions
            catch (Exception exp)
            {
                // set ImageSource to null
                ImageS = null;

            }



        }
    }


}


@FreakyAli
Copy link
Owner

@Tricky0815 Thanks for your solution, Happy that it worked out. I would like to keep this open so I can pick this up whenever in my opinion I have enough time and make this an inbuilt feature. Hope you don't mind!
I will also remember to inform you have an optimized solution as well

@FreakyAli
Copy link
Owner

FreakyAli commented Oct 2, 2023

@Tricky0815 Keep an eye out for #86 I am planning to release it by the weekend maybe sooner as a pre-release but this will be out soon, does not have caching implemented yet but I will do that soon too.

To add this i had to write the whole control again from scratch 😄

Hope its useful to you!

@FreakyAli FreakyAli self-assigned this Oct 2, 2023
@FreakyAli FreakyAli linked a pull request Oct 4, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants