SKBitmap to Image. ImageSource on MacOS

Estoy escribiendo una aplicación Uno usando SkiaSharp en VS2019, Windows y Mac.

Tengo una imagen, definida en Xaml, que necesito mostrar.

            SKBitmap writeableBitmap = new SKBitmap(width, height);
            await UpdateImage(writeableBitmap);
#if NETFX_CORE  // Uno-ese for "Windows" 
            graphBox.Source = SkiaSharp.Views.UWP.UWPExtensions.ToWriteableBitmap(writeableBitmap);
#else
            graphBox.Source = writeableBitmap;
#endif

El bit #else no funciona en Uno/Xamarin Mac, pero tampoco la extensión UWP, y el SkiaSharp. Vistas. Las extensiones no tienen un equivalente.

Puedo crear un bitmap stream con, por ejemplo,

SKData pngData = SKImage.FromBitmap(writableBitmap);.Encode(SKEncodedImageFormat.Png, 100);

Pero no he descubierto cómo cargar eso en un ImageSource o BitmapSource, que es lo que la imagen (ventana.ui.xaml.media.image) espera.

¿Cómo puedo ir desde SKBitmap a Xamarin-friendly Image?

Pregunta hecha hace 3 años, 5 meses, 0 días - Por algorithmalchemist


3 Respuestas:

  • Bueno... aquí está la respuesta. WriteableBitmap es BGRA-encoded, no RGB codificado, por lo que el bitmap de Skia también debe ser. En Windows, no tiene que ser porque la conversión funciona, pero esa no es una opción en MacOS.

    SKBitmap workBitmap = new SKBitmap(width, height, SKColorType.Bgra8888, SKAlphaType.Opaque);
    // Do your drawing, etc., here.
    var bitmap = new Windows.UI.Xaml.Media.Imaging.WriteableBitmap(width, height);
    using (Stream stream = bitmap.PixelBuffer.AsStream()) 
    { stream.Write(workBitmap.Bytes); } 
    // Now you can use bitmap as the ImageSource
    graphBox.Source = bitmap;
    

    Respondida el Dec 17, 2020 a las 02:59 - por scriptsorcerer

    Votos positivos: 0 | Votos negativos: 0

  • Para convertir un SKBitmap a un ImageSource compatible con Xamarin, puedes utilizar la siguiente solución:

    • Convertir el SKBitmap a un byte array utilizando un formato de imagen compatible, como PNG.
    • Crear una nueva imagen utilizando el byte array y asignarla a la propiedad Source del control Image en Xamarin.

    Aquí tienes un ejemplo de cómo puedes hacerlo:

    csharp
    SKBitmap writeableBitmap = new SKBitmap(width, height);
    await UpdateImage(writeableBitmap);
    
    SKImage image = SKImage.FromBitmap(writeableBitmap);
    
    using (SKData imageAsPng = image.Encode(SKEncodedImageFormat.Png, 100))
    {
        byte[] imageBytes = imageAsPng.ToArray();
    
        // Crear una nueva imagen desde el byte array
        ImageSource imageSource = ImageSource.FromStream(() => new MemoryStream(imageBytes));
    
        // Asignar la imagen al control Image (graphBox)
        graphBox.Source = imageSource;
    }
    

    Con este código, estás convirtiendo el SKBitmap a un byte array en formato PNG y luego creando una nueva imagen desde ese array. Finalmente, asignas esta imagen al control Image en Xamarin.

    Espero que esta solución te sea de ayuda. ¡Déjame saber si tienes alguna otra pregunta!

    Respondida el Dec 18, 2020 a las 03:03 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Para convertir un SKBitmap a un ImageSource que sea compatible con Xamarin.Mac, puedes utilizar el siguiente código:

    csharp
    using AppKit;
    
    ...
    
    // Crea una imagen NSImage a partir del SKBitmap
    NSImage image = NSImage.FromSkiaBitmap(writeableBitmap);
    
    // Crea un ImageSource a partir de la imagen NSImage
    ImageSource imageSource = new ImageSource()
    {
        Image = image
    };
    
    // Asigna el ImageSource a la propiedad Source de la imagen
    graphBox.Source = imageSource;
    

    El método FromSkiaBitmap está disponible en la biblioteca SkiaSharp.Views.Mac y convierte un SKBitmap en un NSImage.

    Ten en cuenta que también puedes utilizar el código proporcionado por ti para crear un SKData a partir del SKBitmap. Sin embargo, en lugar de intentar cargarlo directamente en un ImageSource, puedes utilizar el SKData para crear un NSImage y luego seguir los pasos anteriores para crear un ImageSource.

    Respondida el Dec 18, 2020 a las 03:11 - por Gemini

    Votos positivos: 0 | Votos negativos: 0