Search code examples
c#unity-game-engineuwptexture2dwindows-mixed-reality

Unity UWP load image bytes is missing color channels


I´m loading an image bytes and trying to apply it in a Texture2D.

Don't worry about async/await/thread problems...

UWP code:

StorageFile storageFile = StorageFile.GetFileFromPathAsync(filePath).AsTask().GetAwaiter().GetResult();

// get image size
IRandomAccessStreamWithContentType random = storageFile.OpenReadAsync().AsTask().GetAwaiter().GetResult();
BitmapDecoder decoder = BitmapDecoder.CreateAsync(random).AsTask().GetAwaiter().GetResult();
BitmapFrame bitmapFrame = decoder.GetFrameAsync(0).AsTask().GetAwaiter().GetResult();
PixelDataProvider pixelData = bitmapFrame.GetPixelDataAsync().AsTask().GetAwaiter().GetResult();

return new Dictionary<string, object>
{
    {"bytes", pixelData.DetachPixelData()},
    {"width", (int) decoder.PixelWidth},
    {"height", (int) decoder.PixelHeight}
};

Unity code:

Texture2D texture = new Texture2D(textureSizeStruct.width, textureSizeStruct.height, TextureFormat.RGBA32, false);

texture.LoadRawTextureData(textureBytes);
texture.Apply();

This is how the images show up...

Original: enter image description here

In the app (sorry for the big white square): enter image description here


Solution

  • In UWP side get the pixels from decoder with the right params is needed. Follow below the solution:

    StorageFile storageFile = StorageFile.GetFileFromPathAsync(filePath).AsTask().GetAwaiter().GetResult();
    IRandomAccessStreamWithContentType random = storageFile.OpenReadAsync().AsTask().GetAwaiter().GetResult();
    BitmapDecoder decoder = BitmapDecoder.CreateAsync(random).AsTask().GetAwaiter().GetResult();
    
    // here is the catch
    PixelDataProvider pixelData = decoder.GetPixelDataAsync(
        BitmapPixelFormat.Rgba8, // <--- you must to get the pixels like this
        BitmapAlphaMode.Straight,
        new BitmapTransform(),
        ExifOrientationMode.RespectExifOrientation,
        ColorManagementMode.DoNotColorManage // <--- you must to set this too
    ).AsTask().GetAwaiter().GetResult();