Convert CanvasRenderTarget to ImageSource in WinUI

258 Views Asked by At

I'm working on .Net MAUI and I used native rendering in my application. So for Windows (WinUi-3), I have drawings rendered on the CanvasRenderTarget object and now I have to provide this as ImageSource(MAUI) to the user.

I tried to get Pixels from canvasrendertarget object and later to the stream source. But setting this stream source to the Image control, I'm not able to get the image output.

             renderTarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(),(float) 400, (float)400, 96);
             using (var ds = renderTarget.CreateDrawingSession())
             {     
                ds.FillCircle(10, 10, 400, Windows.UI.Color.FromArgb(250, 140, 120, 150));
             }
    
             byte[] bytes = renderTarget.GetPixelBytes();

            //Setting the Stream source to my Image control
            imageview.Source = ImageSource.FromStream(() => new MemoryStream(bytes));

Not sure what I'm missing, how can I convert WinUi RenderTarget object to MAUI.ImageSource ?

1

There are 1 best solutions below

3
On

You are trying to create an ImageSource from raw pixel data, however FromStream expects an encoded PNG or JPG image instead.

To be able to achieve this, you will need to encode that raw pixel data first - luckily there is already an implementation for doing so in Windows.Graphics.Imaging.BitmapEncoder.

Here is a working version of your code snippet, where we create a BitmapEncoder that will convert pixel data to a PNG image. Then, it's just a matter of calling SetPixelData with the appropriate parameters to generate said image:

            var renderTarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), (float)400, (float)400, 96);

            using (var ds = renderTarget.CreateDrawingSession())
            {
                ds.FillCircle(10, 10, 400, Windows.UI.Color.FromArgb(250, 140, 120, 150));
            }

            byte[] bytes = renderTarget.GetPixelBytes();

            var stream = new InMemoryRandomAccessStream();
            var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
            encoder.SetPixelData(BitmapPixelFormat.Rgba8 , BitmapAlphaMode.Straight, 400, 400, 96, 96, bytes);
            await encoder.FlushAsync();

            //Setting the Stream source to my Image control
            imageview.Source = ImageSource.FromStream(() => stream.AsStream());