如何在内存中翻转图像?

时间:2014-03-19 22:43:44

标签: c# image xna flip texture2d

我想翻转图像并创建翻转图像的新Texture2D。

我做了一些研究,发现这段代码会创建一个新的Texture2D;

RenderTarget2D newTarget = new RenderTarget2D(GraphicsDevice, partWidth, partHeight)

GraphicsDevice.SetRenderTarget(newTarget);

SpriteBatch.Draw(original, Vector2.Zero, partSourceRectangle, ... )

GraphicsDevice.SetRenderTarget(null);

Texture2D newTexture = (Texture2D)newTarget;

据我所知,newTexture很容易从内存中删除,所以我被告知我需要使用getData / SetData来创建更永久的纹理。任何人都可以告诉我具体的语法吗?

1 个答案:

答案 0 :(得分:3)

下一个方法将翻转的纹理保存到新的texture2D:

    public Texture2D SaveAsFlippedTexture2D(Texture2D input, bool vertical, bool horizontal)
    {
        Texture2D flipped = new Texture2D(input.GraphicsDevice, input.Width, input.Height);
        Color[] data = new Color[input.Width * input.Height];
        Color[] flipped_data = new Color[data.Length];

        input.GetData<Color>(data);

        for (int x = 0; x < input.Width; x++)
        {
            for (int y = 0; y < input.Height; y++)
            {
                int index = 0;
                if (horizontal && vertical)
                    index = input.Width - 1 - x + (input.Height - 1 - y) * input.Width;
                else if (horizontal && !vertical)
                    index = input.Width - 1 - x + y * input.Width;
                else if (!horizontal && vertical)
                    index = x + (input.Height - 1 - y) * input.Width;
                else if (!horizontal && !vertical)
                    index = x + y * input.Width;

                flipped_data[x + y * input.Width] = data[index];
            }
        }

        flipped.SetData<Color>(flipped_data);

        return flipped;
    }  

实施例: 加载我们的纹理然后使用该方法,将我们的纹理作为参数传递,以将新的翻转纹理返回到另一个纹理。您也可以在游戏Update()方法中加载内容。

    Texture2D texture;
    Texture2D flippedTextureHorizontal;
    Texture2D flippedTextureVertical;
    Texture2D flippedTextureVerticalHorizontal;
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
        texture = Content.Load<Texture2D>("kitty-cat");
        flippedTextureHorizontal = SaveAsFlippedTexture2D(texture, false, true);
        flippedTextureVertical = SaveAsFlippedTexture2D(texture, true, false);
        flippedTextureVerticalHorizontal = SaveAsFlippedTexture2D(texture, true, true);
    }

绘制方法:

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap, DepthStencilState.None, RasterizerState.CullCounterClockwise);
        spriteBatch.Draw(texture, Vector2.Zero, null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
        spriteBatch.Draw(flippedTextureHorizontal, new Vector2(texture.Width + offset, 0), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
        spriteBatch.Draw(flippedTextureVertical, new Vector2(texture.Width * 2 + offset * 2, 0), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
        spriteBatch.Draw(flippedTextureVerticalHorizontal, new Vector2(texture.Width * 3 + offset * 3, 0), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
        spriteBatch.End();
        base.Draw(gameTime);
    }

输出继电器: Output

也可以找到alghorithm Here。 通过使用以下代码同时进行水平和垂直翻转,可以获得与上述相同的结果: 但不确定它是否100%正确

test = new Texture2D(GraphicsDevice, texture.Width, texture.Height);
int size = texture.Width * texture.Height;
Color[] data = new Color[size];
texture.GetData<Color>(data);
Array.Reverse(data, texture.Width, size - texture.Width);
test.SetData<Color>(data);