Forum Libraries, Components, and Plugins
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

How to use FFImageLoading with an Image/ImageButton for SVGs

Hi
I've been trying to use the FFImageLoading NuGet package to utilise SVGs (which for me, are embedded resources) in my project, and have been trying to use them with regular <Image/> and <ImageButton/> elements. On the online docs, they say to do the following:

Which I have done in my MainActivity and AppDelegate projects. But I still can't seem to get an SVG to work on a regular Image or ImageButton. I have tried the following attempts:

<ImageButton WidthRequest="50" Source="ExampleProject.SVGs.ContactPhone.svg"/>
<ImageButton WidthRequest="50" Source="resource://ExampleProject.SVGs.ContactPhone.svg"/>

But neither of them work. Is there something I'm missing? It's not very clear how you do the code in the xaml side.
The Images work if I set the source programatically so it's nothing wrong with the packages being installed, but I want to get it to work inside xaml.

Thanks in advance,
Jamie

Best Answer

Answers

  • ColeXColeX Member, Xamarin Team Xamurai
    edited October 13

    Take a look at Embedded images , please follow the steps as below

    1 . Set Build Action to EmbeddedResource on the image file .

    2 . Create a class which converter from string to ResourceImageSource

    [ContentProperty (nameof(Source))]
    public class ImageResourceExtension : IMarkupExtension
    {
     public string Source { get; set; }
    
     public object ProvideValue (IServiceProvider serviceProvider)
     {
       if (Source == null)
       {
         return null;
       }
    
       // Do your translation lookup here, using whatever method you require
       var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);
    
       return imageSource;
     }
    }
    

    3 . Usage in xaml

    <?xml version="1.0" encoding="UTF-8" ?>
    <ContentPage
       xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:WorkingWithImages;assembly=WorkingWithImages"
       x:Class="WorkingWithImages.EmbeddedImagesXaml">
     <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
       <!-- use a custom Markup Extension -->
       <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
     </StackLayout>
    </ContentPage>
    
  • JamieColcloughJamieColclough Member
    edited October 13

    1 . Set Build Action to EmbeddedResource on the image file .

    2 . Create a class which converter from string to ResourceImageSource

    [ContentProperty (nameof(Source))]
    public class ImageResourceExtension : IMarkupExtension
    {
     public string Source { get; set; }
    
     public object ProvideValue (IServiceProvider serviceProvider)
     {
       if (Source == null)
       {
         return null;
       }
    
       // Do your translation lookup here, using whatever method you require
       var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);
    
       return imageSource;
     }
    }
    

    3 . Usage in xaml

    <?xml version="1.0" encoding="UTF-8" ?>
    <ContentPage
       xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:WorkingWithImages;assembly=WorkingWithImages"
       x:Class="WorkingWithImages.EmbeddedImagesXaml">
     <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
       <!-- use a custom Markup Extension -->
       <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
     </StackLayout>
    </ContentPage>
    

    @ColeX This worked perfectly and I've managed to get it working :)
    For the sake of people reading this thread hoping to get it working specifically for FFImageLoading, you will also need to include a width and/or a height property in the SvgImageSource.FromResource() method to get the SVG to load in the right size.
    To access the width and height using the WidthRequest and HeightRequest properties that you would usually put on the xaml of the image, you can use the IServiceProvider inside the ProvideValue method as follows:

            public object ProvideValue(IServiceProvider serviceProvider)
            {
                if (Source == null)
                {
                    return null;
                }
                IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
                Image image = provideValueTarget.TargetObject as Image;
                if(image != null)
                {
                    Width = (int)image.Width;
                    Height = (int)image.Height;
                }
                var imageSource = SvgImageSource.FromResource(Source, typeof(SVGResourceExtension).Assembly, Width, Height);
    
                return imageSource;
            }
    

    And that'll work easily with

    <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" WidthRequest="50" HeightRequest="50"/>
    
Sign In or Register to comment.