question

IgorKravchenko-7896 avatar image
0 Votes"
IgorKravchenko-7896 asked IgorKravchenko-7896 answered

How to get native image (bitmap) from ImageSource?

I need to get native bitmap from ImageSource. In Xamarin Forms we have a LoadImageAsync method in IImageSourceHandler. And for example to get bitmap from FontImageSource we needed to create FontImageSourceHandler and call LoadImageAsync.
How to get bitmap in MAUI?

For example, I have a custom entry with property LeadingImageSource of type ImageSource. And I want to use this in handler.

 public static void MapImage(IMaterialEntryHandler handler, IMaterialEntry entry)
         {
             Bitmap bitmap = entry.LeadingImageSource //how to get from ImageSource?
             BitmapDrawable leadingDrawable = new BitmapDrawable(handler.MauiContext.Context.Resources, bitmap);
             handler.PlatformView.EditText.SetCompoundDrawablesWithIntrinsicBounds(leadingDrawable, null, null, null);
         }

I found ImageSourcePartLoader class but this is not clear for me how to use it. I see in maui sources usage like this: new ImageSourcePartLoader(this, () => VirtualView, OnSetImageSource);.
Should I implement IImageSourcePart to get bitmap and use it in OnSetImageSource?
Thanks.

dotnet-maui
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

LeonLu-MSFT avatar image
1 Vote"
LeonLu-MSFT answered IgorKravchenko-7896 commented

Hello,​

Firstly, you need to get the MaterialEntry by entry, then get ImageSource by LeadingImageSource.

Then you can convert ImageSource to IImageSourceHandler, please notice you need to convert specific ImageSourceHandler by ImageSource type.

In the end, you can get Bitmap by await iImageSourceHandler.LoadImageAsync(imageSource, MainActivity.Instance);, You can refer to following code


public static async void MapImage(IMaterialEntryHandler handler, IMaterialEntry entry)
         {
         //    Bitmap bitmap = entry.LeadingImageSource //how to get from ImageSource?

           if (entry != null)
            {

                MaterialEntry materialEntry = entry as MaterialEntry;
                ImageSource imageSource = materialEntry.LeadingImageSource;

                IImageSourceHandler iImageSourceHandler;

                if (imageSource is FileImageSource)
                {
                    iImageSourceHandler = new FileImageSourceHandler();
                }
                else if (imageSource is StreamImageSource)
                {
                    iImageSourceHandler = new StreamImagesourceHandler(); // sic
                }
                else if (imageSource is UriImageSource)
                {
                    iImageSourceHandler = new ImageLoaderSourceHandler(); // sic
                }
                else
                {
                    throw new NotImplementedException();
                }

                Bitmap bitmap = await iImageSourceHandler.LoadImageAsync(imageSource, MainActivity.Instance);
            }

         }


Best Regards,

Leon Lu



If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

IgorKravchenko-7896 avatar image
0 Votes"
IgorKravchenko-7896 answered

Hi.
I get error when calling handler.LoadImageAsync (handler is FontImageSourceHandler).

 System.InvalidOperationException: IMauiContext not found.
 [mono-rt]    at Microsoft.Maui.Controls.ViewExtensions.RequireMauiContext(Element element, Boolean fallbackToAppMauiContext) in D:\a\_work\1\s\src\Controls\src\Core\ViewExtensions.cs:line 200
 [mono-rt]    at Microsoft.Maui.Controls.ViewExtensions.RequireFontManager(Element element, Boolean fallbackToAppMauiContext) in D:\a\_work\1\s\src\Controls\src\Core\ViewExtensions.cs:line 217
 [mono-rt]    at Microsoft.Maui.Controls.Compatibility.Platform.Android.FontImageSourceHandler.LoadImageAsync(ImageSource imagesource, Context context, CancellationToken cancelationToken) in D:\a\_work\1\s\src\Compatibility\Core\src\Android\Renderers\FontImageSourceHandler.cs:line 36
 [mono-rt]    at TcuMaui.Platforms.Android.Extensions.Extensions.ToBitmap(ImageSource imageSource, CancellationToken cancellationToken) in C:\Users\Igor\source\Workspaces\TcuMaui\TcuMaui\Platforms\Android\Extensions\Extensions.cs:line 31

Code:

 public static IImageSourceHandler GetHandler(this ImageSource imageSource)
         {
             if (imageSource is FileImageSource)
                 return new FileImageSourceHandler();
             if (imageSource is StreamImageSource)
                 return new StreamImagesourceHandler();
             if (imageSource is UriImageSource)
                 return new ImageLoaderSourceHandler();
             if (imageSource is FontImageSource)
                 return new FontImageSourceHandler();
             return null;
         }
    
         public static Task<Bitmap> ToBitmap(this ImageSource imageSource, CancellationToken cancellationToken = default)
         {
             if (imageSource == null)
                 return null;
             IImageSourceHandler handler = imageSource.GetHandler();
             return handler.LoadImageAsync(imageSource, MainActivity.Instance, cancellationToken);
         }
    
         public static async Task<BitmapDrawable> ToBitmapDrawable(this ImageSource imageSource, CancellationToken cancellationToken = default)
         {
             if (imageSource == null)
                 return null;
             Bitmap bitmap = await imageSource.ToBitmap(cancellationToken);
             return new BitmapDrawable(MainActivity.Instance.Resources, bitmap);
         }

I use FontImageSource in custom control.

 <controls:MaterialEntry Placeholder="Contractor">
                 <controls:MaterialEntry.LeadingImageSource>
                     <FontImageSource FontFamily="MaterialOutline"
                                      Glyph="{Static icons:MaterialOutline.Person}"
                                      Color="Blue"/>
                 </controls:MaterialEntry.LeadingImageSource>
             </controls:MaterialEntry>

Full project
How can I solve this issue? Thanks.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.