简体   繁体   English

如何在内存中翻转图像?

[英]How do I flip an image in memory?

I would like to flip an image and create a new Texture2D of that flipped image. 我想翻转图像并创建翻转图像的新Texture2D。

I have done some research and found that this code will create a new 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;

I understand that the newTexture is susceptible to being removed from memory so I am advised that I need to use getData/SetData to create a more permanent texture. 我知道newTexture很容易被从内存中删除,所以我被告知我需要使用getData / SetData来创建更永久的纹理。 Could anyone advise me on the specific syntax to do this? 任何人都可以告诉我具体的语法来做到这一点?

The next method saves flipped texture to new texture2D: 下一个方法将翻转的纹理保存到新的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;
    }  

Example: Load our texture then use the method, pass our texture as parameter to return new flipped texture to another texture. 示例:加载纹理然后使用方法,将纹理作为参数传递,以将新的翻转纹理返回到另一个纹理。 You can load your content inside game Update() method as well. 您也可以在游戏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);
    }

Draw method: 绘制方法:

    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);
    }

Ouput: 输出继电器: 产量

The alghorithm can be found Here as well. 该alghorithm可以发现这里也。 The same result as above can be achieved by using code below for horizontal and vertical flipping at the same time: But not sure it will be 100% correct 通过使用以下代码同时进行水平和垂直翻转,可以获得与上述相同的结果:但不确定它是否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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM