Whilst I was working on migrating the WeatherTwentyOne app from Maui to Uno I noticed that the Maui application includes a number images as SVG files. However, in the XAML there are only ever references to PNG files. On closer inspection of the bin folder for the WinUI project I noticed that for each SVG file, 5 different PNG files were being generated at different scales (100, 125, 150 200 and 400). Looking at the other platforms I noticed similar behaviour where the SVG file had been used to generate PNG images in the appropriate scale for the platform. In this post we’re going to look at how we can use this feature in a WinUI / Uno application instead of a Maui application.
For the purpose of this post I’m going to start with a new WinUI+Uno application which can be generated from the unoapp-winui dotnet template (eg dotnet new unoapp-winui -o ImageUnoSample). I’m going add a reference to the Microsoft.Maui.resizetizer package (eg add the following to the csproj files for each target platform <PackageReference Include=”Microsoft.Maui.resizetizer” Version=”6.0.100-preview.5.794″/>)
Now all we need to do is add some images. Let’s start with just adding some SVGs, which I’m actually going to borrow from the WeatherTwentyOne project. When you add the SVG files to a project, you need to set the Build Action to Content so that the files are packaged with the application. We can reference these in the XAML as follows:
<Grid Height="100" Width="100" > <Image Source="ms-appx:///compass_background.svg" /> <Image Source="ms-appx:///compass_needle.svg"/> </Grid>
This will work nicely on platforms that support SVG files, such as WinUI. However, for other platforms the images will just be missing. So take advantage of the Resizetizer library we need to make two changes. Firstly, we need to change the Build Action for the SVG file to MauiImage. You won’t be able to do this via the Properties tool window. Instead, you need to open the projitems file that defines the files that are included in the Shared project (Note that if you’re not using Uno, you just need to manually edit the csproj file for this step). Change the XML from:
<Content Include="$(MSBuildThisFileDirectory)compass_background.svg" /> <Content Include="$(MSBuildThisFileDirectory)compass_needle.svg" />
<MauiImage Include="$(MSBuildThisFileDirectory)compass_background.svg" /> <MauiImage Include="$(MSBuildThisFileDirectory)compass_needle.svg" />
The other change we need to make is where we reference the image files in XAML. Instead of referencing the SVG file, we need to change the file extension to PNG. We also need to add Assets to the path, for example.
<Grid Height="100" Width="100" > <Image Source="ms-appx:///Assets/compass_background.png" /> <Image Source="ms-appx:///Assets/compass_needle.png"/> </Grid>
Now when you build and run the application you’ll notice that the application package includes the PNG files.
On Android I had to include the following in the first PropertyGroup in csproj – <AndroidApplication>true</AndroidApplication> in order to coerce the resizetizer to run. iOS should work without any further modifications to the csproj file.
Updated 6th July 2021:
At this stage I haven’t been able to get this to work with WASM – For WASM you can force the resizer to run by including <_ResizetizerIsWinUIApp>true</_ResizetizerIsWinUIApp> in the csproj (faking that it’s a WinUI application) which generates the files but for some reason they’re not being included in the generated package. To include the generated files in the WASM output you can then add the following to the csproj <Content Include=”obj\$(Configuration)\net5.0\resizetizer\r\Assets*.png” Link=”Assets\%(Filename)%(Extension)” />
Hopefully as Maui progresses towards a stable release, some of these hacks may get resolved, which would allow the Resizetizer to be used across any application type.