locked
How to use FFImageLoading with an Image/ImageButton for SVGs RRS feed

  • Question

  • User397252 posted

    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

    Monday, October 12, 2020 4:14 PM

Answers

  • User369978 posted

    @JamieColclough said:

    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 ```

    If problem has been solved could you mark the solution as answer ? It's helpful to others who's facing the same problem.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, October 15, 2020 1:47 AM

All replies

  • User369978 posted

    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>

    Tuesday, October 13, 2020 8:48 AM
  • User397252 posted

    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 ```

    Tuesday, October 13, 2020 9:55 AM
  • User369978 posted

    @JamieColclough said:

    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 ```

    If problem has been solved could you mark the solution as answer ? It's helpful to others who's facing the same problem.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, October 15, 2020 1:47 AM
  • User395644 posted

    Thanks for this solution. It works for me. But, just to completed the answer with the problem I faced, the name of the image has to mentioned the name of the assembly : "Project.Folder.ImageName.Ext". I decide to handle this in the MarkupExtension :

    Assembly assembly = typeof(ImageResourceExtension).GetTypeInfo().Assembly; var imageSource = ImageSource.FromResource($"{assembly.GetName().Name}.{Source}", typeof(ImageResourceExtension).GetTypeInfo().Assembly);

    Sunday, January 10, 2021 8:39 AM