XNA Texture2D.FromStream以1

时间:2018-03-01 17:37:18

标签: c# xna textures

我目前正在加载并将用作映射图像的Texture2D保存到数据库中,以便以后可以预加载它们。每个颜色通道需要是加载后保存时的精确颜色。问题是Texture2D.FromStream有时会返回错误的颜色通道,有时关闭1个左右。这是不可接受的,因为如果映射的颜色不正确,它们将毫无用处。

下面的示例提供了一种情况,当alpha设置为100时,RGB为255,将RGB更改为254.当将alpha设置为1或255时,它们正确地返回255,其他alpha值会导致相同的问题为100。

Texture2D tex = new Texture2D(GraphicsDevice, 20, 20, false, SurfaceFormat.Color);
Color[] data = new Color[tex.Width * tex.Height];
for (int i = 0; i < data.Length; i++) {
    data[i] = new Color(255, 255, 255, 100);
}
tex.SetData<Color>(data);
using (Stream stream = File.Open("TestAlpha.png", FileMode.OpenOrCreate)) {
    tex.SaveAsPng(stream, tex.Width, tex.Height);
    stream.Position = 0;
    tex = Texture2D.FromStream(GraphicsDevice, stream);
    tex.GetData<Color>(data);
    Console.WriteLine(data[0]); // Returns (R:254 G:254 B:254 A:100)
}

我在Paint.NET中查看保存的图像时确认png具有正确的RGB 255,因此它只能是在Texture2D.FromStream期间导致的。

1 个答案:

答案 0 :(得分:0)

好吧,我找不到Texture2D.FromStream问题的原因,但我找到了一种全方位的加载Texture2D的方法。在这种情况下,我从流中加载GDI Bitmap,获取其数据,然后将其传输到新创建的Texture2D

我打算使用它,无论Texture2D.FromSteam是否可以修复,但我仍然想知道是否有人知道它是怎么回事。

对于那些新手,请确保包含System.Drawing作为参考,因为默认情况下它不在XNA项目中。

public static unsafe Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream) {
    // Load through GDI Bitmap because it doesn't cause issues with alpha
    using (Bitmap bitmap = (Bitmap) Bitmap.FromStream(stream)) {
        // Create a texture and array to output the bitmap to
        Texture2D texture = new Texture2D(graphicsDevice,
            bitmap.Width, bitmap.Height, false, SurfaceFormat.Color);
        Color[] data = new Color[bitmap.Width * bitmap.Height];

        // Get the pixels from the bitmap
        Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
        BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly,
            PixelFormat.Format32bppArgb);

        // Write the pixels to the data buffer
        byte* ptr = (byte*) bmpData.Scan0;
        for (int i = 0; i < data.Length; i++) {
            // Go through every color and reverse red and blue channels
            data[i] = new Color(ptr[2], ptr[1], ptr[0], ptr[3]);
            ptr += 4;
        }

        bitmap.UnlockBits(bmpData);

        // Assign the data to the texture
        texture.SetData<Color>(data);

        // Fun fact: All this extra work is actually 50% faster than
        // Texture2D.FromStream! It's not only broken, but slow as well.

        return texture;
    }
}