Ffimageloading: How to use ffimageloadingsvg within an ImageButton

Created on 24 Jan 2019  路  4Comments  路  Source: luberda-molinet/FFImageLoading

Any hints on how to use FFImageLoading.Svg.Forms within ImageButton using xaml? Or at least let me know if it's possible. I've wasted so many hours I fear.

Most helpful comment

You can now easily use FFImageLoading in >= XF 4.0 with this: https://github.com/luberda-molinet/FFImageLoading/wiki/Xamarin.Forms-Advanced#iimageviewhandler--iimagesourcehandler

Just use SvgImageSource as a Source

All 4 comments

I dont think you can do

Seems like this extension should work but for some reason it doesn't even though there are no errors.

Xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:ext="clr-namespace:MyApp.Extensions"
              ... etc... >
<ContentPage.Resources>
        <ResourceDictionary>
            <x:String x:Key="TestImg">MyApp.Resources.top.svg</x:String>
    </ContentPage.Resources>
<ImageButton Source="{ext:SvgImageResource Source={StaticResource TestImg}}" ... etc

Extension

[ContentProperty(nameof(Source))]
    public class SvgImageResourceExtension : IMarkupExtension
    {
        public string Source { get; set; }
        ImageSource imgSource;

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Source == null)
            {
                return null;
            }

            Assembly assembly = typeof(SvgImageResourceExtension).GetTypeInfo().Assembly;
            using (Stream stream = assembly.GetManifestResourceStream(Source))
            {
                GetImgSource(stream);
            }
            return imgSource;
        }

        private void GetImgSource(Stream source)
        {
            SKSvg svg = new SKSvg();
            svg.Load(source);
            var _bitmap = new SKBitmap((int)svg.CanvasSize.Width, (int)svg.CanvasSize.Height);
            using (SKBitmap bitmap = new SKBitmap((int)svg.CanvasSize.Width, (int)svg.CanvasSize.Height))
            using (SKCanvas canvas = new SKCanvas(bitmap))
            {
                canvas.DrawPicture(svg.Picture);
                canvas.Flush();
                canvas.Save();

                using (SKImage image = SKImage.FromBitmap(bitmap))
                using (SKData data = image.Encode(SKEncodedImageFormat.Png, 80))
                using (MemoryStream memStream = new MemoryStream())
                {
                    data.SaveTo(memStream);
                    memStream.Seek(0, SeekOrigin.Begin);
                    imgSource = ImageSource.FromStream(() => memStream);
                }
            }


        }
    }

I got it to work using the following extension.

Using statements:

using SkiaSharp;
using System;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using SKSvg = SkiaSharp.Extended.Svg.SKSvg;

Code

[ContentProperty(nameof(Source))]
    public class SvgImageResourceExtension : IMarkupExtension
    {
        public string Source { get; set; }
        ImageSource imgSource;

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Source == null)
            {
                return null;
            }

            Assembly assembly = typeof(SvgImageResourceExtension).GetTypeInfo().Assembly;
            using (Stream stream = assembly.GetManifestResourceStream(Source))
            {
                GetSvg(stream);
            }
            return imgSource;
        }

        private void GetSvg(Stream strm)
        {
            SKSvg svg = new SKSvg();
            svg.Load(strm);
            var _bitmap = new SKBitmap((int)svg.CanvasSize.Width, (int)svg.CanvasSize.Height);
            using (SKBitmap bitmap = new SKBitmap((int)svg.CanvasSize.Width, (int)svg.CanvasSize.Height))
            using (SKCanvas canvas = new SKCanvas(bitmap))
            {
                canvas.DrawPicture(svg.Picture);
                canvas.Flush();
                canvas.Save();

                using (SKImage image = SKImage.FromBitmap(bitmap))
                using (SKData data = image.Encode(SKEncodedImageFormat.Png, 100))
                using (MemoryStream memStream = new MemoryStream())
                {
                    data.SaveTo(memStream);
                    memStream.Seek(0, SeekOrigin.Begin);
                    imgSource = ImageSource.FromStream(() => memStream);

                    string sFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), GetFileNameFromSource());

                    if (File.Exists(sFile))
                    {
                        imgSource = ImageSource.FromStream(() => File.OpenRead(sFile));
                    }
                    else
                    {
                        FileStream fileStream = new FileStream(sFile, FileMode.Create);
                        memStream.CopyTo(fileStream);
                        imgSource = ImageSource.FromStream(() => File.OpenRead(sFile));
                    }
                }
            }


        }

        private string GetFileNameFromSource()
        {
            var returnstr = "";
            string pattern = @"(\w+\.\w{3})$";
            RegexOptions options = RegexOptions.Multiline;
            foreach (Match m in Regex.Matches(Source, pattern, options))
            {
                returnstr = m.Value;
            }
            return returnstr;
        }
    }

You can now easily use FFImageLoading in >= XF 4.0 with this: https://github.com/luberda-molinet/FFImageLoading/wiki/Xamarin.Forms-Advanced#iimageviewhandler--iimagesourcehandler

Just use SvgImageSource as a Source

Was this page helpful?
0 / 5 - 0 ratings