How can i use canvas.DrawImage to draw a FontImage ?

Fei Xu 490 Reputation points
2023-08-07T16:35:49.6233333+00:00

I need draw some FontImage in GraphicView.

But How can i do it?

canvas.DrawImage need IIamge

Image image = new Image { BackgroundColor = Color.FromArgb("#D1D1D1") };
image.Source = new FontImageSource
{
    Glyph = "\uf30c",
    FontFamily = DeviceInfo.Platform == DevicePlatform.iOS ? "Ionicons" : "ionicons.ttf#",
    Size = 44
};


IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
#if IOS || ANDROID || MACCATALYST
    // PlatformImage isn't currently supported on Windows.
    image = PlatformImage.FromStream(stream);
#elif WINDOWS
    image = new W2DImageLoadingService().FromStream(stream);
#endif
}

if (image != null)
{
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}
Developer technologies | .NET | .NET MAUI
{count} votes

2 answers

Sort by: Most helpful
  1. Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) 36,436 Reputation points Microsoft External Staff
    2023-08-14T09:33:00.0666667+00:00

    Hello,

    There is a known issue reported at GitHub - Need a way to convert an ImageSource into an IImage. · Issue #10624 (github.com), please follow the progress. This issue doesn't mention FontImage, you could add comments at GitHub or create a new feature request.

    As I understood, you want to convert the image to Stream, then create a new IImage. After the image is loaded on the page, the handler won't be null. And you can get the handler in the Loaded method, then get the stream and call canvas.DrawImage method. Please refer to the following code on iOS platform:

    XAML

    <VerticalStackLayout>
            <Label
                Text="Welcome to .NET MAUI!"
                VerticalOptions="Center"
                HorizontalOptions="Center" />
            <Image x:Name="MyFontImage" BackgroundColor="#D1D1D1">
        <Image.Source>
            <FontImageSource Glyph="&#xf30c;"
                             FontFamily="{OnPlatform iOS=Ionicons, Android=ionicons.ttf#}"
                             Size="44" />
        </Image.Source>
    </Image>
    <GraphicsView x:Name="MyGraphyView" BackgroundColor="#D1D1D1"
                              HeightRequest="200"
                              WidthRequest="400" />
    </VerticalStackLayout>
    

    Loaded method:

    public NewPage1()
          {
                InitializeComponent();
            this.Loaded += NewPage1_Loaded;
        }
    

    Setting Drawable

    private void NewPage1_Loaded(object sender, EventArgs e)
        {
            MyGraphyView.Drawable = new ImagePaintDrawable(MyFontImage);
        }
    

    Drawable

    internal class ImagePaintDrawable : IDrawable
        {
            public Image MyFontImage { get; set; } = new Image();
            public ImagePaintDrawable(Image image)
            {
                MyFontImage = image;// pass the image
            }
           public void Draw(ICanvas canvas, RectF dirtyRect)
            {
    #if IOS || ANDROID || MACCATALYST
                IImage image;
    #if IOS
                UIKit.UIImageView uIImage = MyFontImage.Handler.PlatformView as UIKit.UIImageView;// handler won't be null
                var A = uIImage.Image;
                Stream imageStream = A.AsPNG().AsStream();
                image = PlatformImage.FromStream(imageStream);//get stream (iOS platform)
               if (image != null)
                {
                    canvas.DrawImage(image, 10, 10, image.Width, image.Height);// draw
                }
    #endif
    #endif
            }
        }
    

    Best Regards,

    Wenyan Zhang


    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.


  2. Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) 36,436 Reputation points Microsoft External Staff
    2023-08-29T06:46:38.9566667+00:00

    Hello,

    Since you cannot get the stream, it's recommended that you try to draw a string.

    Steps:

    Register font in MauiProgram class.

    builder
    			.UseMauiApp<App>()
    			.ConfigureFonts(fonts =>
    			{
    				fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
    				fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                    fonts.AddFont("ionicons.ttf", "ionicons");
                });
    

    Define Drawable, please pay attention to adding the .ttf suffix for Android and #fontfamily for Windows platform.

    internal class FontDrawable : IDrawable
    {
        public void Draw(ICanvas canvas, RectF dirtyRect)
        {
            canvas.FontColor = Colors.Black;
            canvas.FontSize = 50;
    #if IOS
            canvas.Font = new Microsoft.Maui.Graphics.Font("ionicons");
    #elif ANDROID
            canvas.Font = new Microsoft.Maui.Graphics.Font("ionicons.ttf");
    #else
            canvas.Font = new Microsoft.Maui.Graphics.Font("ionicons.ttf#ionicons");
    #endif
            canvas.DrawString("\uf30c", 0, 0, dirtyRect.Width, dirtyRect.Height, HorizontalAlignment.Center, VerticalAlignment.Center);
    
       }
    }
    

    Best Regards,

    Wenyan Zhang


    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.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.