maui icon indicating copy to clipboard operation
maui copied to clipboard

Need a way to convert an ImageSource into an IImage.

Open GuildOfCalamity opened this issue 2 years ago • 12 comments

Description

Would love to have a way for the ImageSource object to be converted to IImage for Canvas.DrawImage calls on Windows environments.

Public API Changes

var imgSource = ImageSource.FromStream(() => stream).ToIImage();
/* or */
var imgSource = (IImage)ImageSource.FromStream(() => stream);

Intended Use-Case

The Microsoft.Maui.Graphics.Platform.PlatformImage.FromStream(stream) returns an IImage type, which is not supported on Windows :( There needs to be a cast option or a public converter method so that images can bee used in canvas objects on Windows platforms.

GuildOfCalamity avatar Oct 11 '22 23:10 GuildOfCalamity

https://github.com/dotnet/maui/issues/6742

I don't know if it was really ever solved. It's a part of Maui.Graphics subproject which has been merged into MAUI before release (in April or May 2022) but it was like 60 - 70 % implemented at that moment.

janseris avatar Oct 12 '22 11:10 janseris

@mattleibow

PureWeen avatar Oct 12 '22 18:10 PureWeen

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

ghost avatar Oct 12 '22 18:10 ghost

Does anyone know how to convert between these two? I'm not against adding extra code to handle it, but I can't find any specs on the low-level object types and what their native forms are. If the IImage interface could return raw byte data then there could be a solution created?

GuildOfCalamity avatar Oct 12 '22 22:10 GuildOfCalamity

Maybe you can get the imagesourceservice from the service provider, get the image and then do a new platformimage(img)

Converting back may be harder as the source expects a new image each time, but maybe a new imagesourceservice is something that can be added to always return the same image.

// typing on a phone now

mattleibow avatar Oct 13 '22 00:10 mattleibow

Something like this will get the image from a stream and presumably you can get the stream if you know what you image source is:

var assembly = GetType().GetTypeInfo().Assembly; using (var stream = assembly.GetManifestResourceStream("TDSP.Resources.Images.splash_light_background_no_motto.png")) iimage = PlatformImage.FromStream(stream);

philipag avatar Oct 13 '22 12:10 philipag

@philipag this only applies to images in project resources provided with the application doesn't it

janseris avatar Oct 13 '22 17:10 janseris

@janseris No, it applies to any stream. So if you know the path you can just open the file as a stream:

using (var stream = new FileStream(photo.Path, FileMode.Open)) image = PlatformImage.FromStream(stream);

philipag avatar Oct 13 '22 17:10 philipag

@philipag PlatformImage is MAUI Android API

janseris avatar Oct 13 '22 18:10 janseris

@janseris Microsoft.Maui.Graphics.Platform.PlatformImage is part of Maui and returns a MAUI IImage.

philipag avatar Oct 13 '22 18:10 philipag

@philipag please see here. PlarformImage is not available on MAUI Windows: https://github.com/dotnet/maui/issues/6742

janseris avatar Oct 13 '22 19:10 janseris

As @janseris states, Windows build environments do not support PlatformImage.FromStream()

GuildOfCalamity avatar Oct 13 '22 20:10 GuildOfCalamity

@GuildOfCalamity Do you know a way to convert Image.Source (ImageSource) or Image to Microsoft.Maui.Graphics.IImage for other platforms?

faruknane avatar Jun 03 '23 14:06 faruknane

For Windows platform, you should be able to use W2DImageLoadingService().FromStream to convert a stream to a IImage, otherwise PlatformImage.FromStream for other platforms. To avoid compiler errors, you could have a helper class/method like the following to return an IImage from a stream for all platforms:

using IImage = Microsoft.Maui.Graphics.IImage;
#if !WINDOWS
using Microsoft.Maui.Graphics.Platform;
#else
using Microsoft.Maui.Graphics.Win2D;
#endif

namespace SomeMauiApp.Util
{
    public static class XPlatformImageHelper
    {
        /// <summary>
        /// Gets IImage from image source stream for all platforms.
        /// </summary>
        /// <param name="source">Image source stream.</param>
        /// <returns>MAUI IImage implementation from the image stream.</returns>
        public static IImage GetImageFromStream(Stream source)
        {
          #if WINDOWS
            return new W2DImageLoadingService().FromStream(source);
          #else
            return PlatformImage.FromStream(source);
          #endif
        }
    }
}

So using the above, if you wanted to get an image from resources and then apply to Canvas.DrawImage, this could be done with something like the below:

canvas.DrawImage(XPlatformImageHelper.GetImageFromStream(new MemoryStream(Resources.someImage)), _imgX, _imgY, _imgWidth, _imgHeight);

zerihal avatar Jul 12 '23 11:07 zerihal