Microsoft.Maui.Graphics
Microsoft.Maui.Graphics copied to clipboard
IImageLoadingService cannot load image on Windows
Description
What I was trying to achieve:
- resize an image selected from PC using MAUI on Windows
Result:
- I didn't get past loading the file as
IImage
Sample application:
MauiApp2 Android IImage resized image disposed exception.zip (yes, the same as for https://github.com/dotnet/maui/issues/6909)
Description
Any attempt to load an image using IImageLoadingService on Windows results in this code being called:

"No resource creator has been registered globally or for this thread."
Exception thrown: 'System.Exception' in Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
An exception of type 'System.Exception' occurred in Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll but was not handled in user code
No resource creator has been registered globally or for this thread.
How I am calling it:

imageLoadingService.FromStream which is Microsoft.Maui.Graphics.Win2D.SkiaImageLoadingService which is the only IImageLoadingService implementation which works for me for Windows (during compile-time).
Win2DImage cannot be called directly because it is an internal class.
What I am doing in MauiProgram.cs:
#if WINDOWS
services.AddSingleton<IImageLoadingService, Microsoft.Maui.Graphics.Win2D.SkiaImageLoadingService>();
#endif
#if ANDROID
services.AddSingleton<IImageLoadingService, Microsoft.Maui.Graphics.Platform.PlatformImageLoadingService>();
#endif
Steps to Reproduce
Inject Microsoft.Maui.Graphics.Win2D.SkiaImageLoadingService for IImageLoadingService on Windows and try creating an IImage from file/stream with it.
Version with bug
Release Candidate 2 (current)
Last version that worked well
Unknown/Other
Affected platforms
Windows
Affected platform versions
I don't know.
Did you find any workaround?
No response
Relevant log output
No response
Verified repro on VS 17.3.0 Preview 1.0 [32427.505.main]. Repro project: MauiApp2.Android.IImage.resized.image.disposed.exception.zip
Are there any workarounds possible for this? Perhaps an alternative implementation of IImage for windows that would just get me to a point where I can display an image on a GraphicsView?
@limefrogyank tag some MAUI people to receive any info on this
I found a workaround. Put a dummy GraphicsView on the page somewhere where it loads first and handle the Loaded event with this:
private void dummy_Loaded(object sender, EventArgs e)
{
#if WINDOWS
Assembly assembly = typeof(Microsoft.Maui.Graphics.Win2D.W2DCanvas).Assembly;
var type = assembly.GetType("Microsoft.Maui.Graphics.Win2D.W2DGraphicsService");
var prop = type.GetProperty("GlobalCreator");
var graphicsView = (GraphicsView)sender;
var view = (Microsoft.Maui.Platform.PlatformTouchGraphicsView)graphicsView.Handler.PlatformView;
var view2 = (Microsoft.Maui.Graphics.Win2D.W2DGraphicsView)view.Content;
prop.SetValue(null, view2.Content);
#endif
}
I actually get a COM error the first time I try to load an image, but after the first one (handled via try...catch) it works fine. All of the images load. Maybe there's a timing issue still, but it works for me... at least to get to the next stage of working on my app.
I found a workaround. Put a dummy GraphicsView on the page somewhere where it loads first and handle the Loaded event with this:
private void dummy_Loaded(object sender, EventArgs e) { #if WINDOWS Assembly assembly = typeof(Microsoft.Maui.Graphics.Win2D.W2DCanvas).Assembly; var type = assembly.GetType("Microsoft.Maui.Graphics.Win2D.W2DGraphicsService"); var prop = type.GetProperty("GlobalCreator"); var graphicsView = (GraphicsView)sender; var view = (Microsoft.Maui.Platform.PlatformTouchGraphicsView)graphicsView.Handler.PlatformView; var view2 = (Microsoft.Maui.Graphics.Win2D.W2DGraphicsView)view.Content; prop.SetValue(null, view2.Content); #endif }I actually get a COM error the first time I try to load an image, but after the first one (handled via try...catch) it works fine. All of the images load. Maybe there's a timing issue still, but it works for me... at least to get to the next stage of working on my app.
Is that a workaround only to display the image in UI or to allow loading it as IImage for further processing as well?
This is just to load an stream into an IImage. The error you get comes from the GlobalCreator property being always null. Once you populate it with an actual CanvasControl from Win2D, then the loading a stream into an IImage works.
My dummy GraphicsView is 1 pixel by 1 pixel and it's covered by other controls. The windows version of GraphicsView uses a CanvasControl internally.
Somewhere later in my code, I'm doing this to load an image into an IImage:
var service = new Microsoft.Maui.Graphics.Win2D.W2DImageLoadingService();
IImage _image = service.FromStream(_ms.AsStream(), ImageFormat.Jpeg);
Again, I do get an initial COM error when trying the above code, but it works eventually. (My app is loading several pages from a pdf file as images and displaying them. If it can't get the image, it tries again at the next draw call when the GraphicsView is Invalidated. So this works for me...)
Building on previous suggestions, and after looking at the source for W2DGraphicsService, this is what I came up with, and it's working for me.
You'd think that the getter on line 13 of W2DGraphicsService would have the same result.
#if WINDOWS
builder.Services.AddSingleton<IImageLoadingService>(_ =>
{
var canvasDevice = CanvasDevice.GetSharedDevice();
var assembly = typeof(Microsoft.Maui.Graphics.Win2D.W2DCanvas).Assembly;
var type = assembly.GetType("Microsoft.Maui.Graphics.Win2D.W2DGraphicsService");
var prop = type!.GetProperty("GlobalCreator");
prop!.SetValue(null, canvasDevice);
return new Microsoft.Maui.Graphics.Win2D.W2DImageLoadingService();
});
#endif
Duplicate of https://github.com/dotnet/maui/issues/12370
Backported to net7 https://github.com/dotnet/maui/pull/12690
This was backported to net7 7 months ago. What version are you on?