Search code examples
c#xnacroptexture2d

Cropping texture2d on all sides in xna c#


i am trying to crop a texture2d in xna. i have found the following code which will crop the image on the top and right sides, i have played around with the code and cannot figure a way to crop all sides at a specific interval. below is the code i have been trying to modify:

any help or ideas would be much appreciated.

Rectangle area = new Rectangle(0, 0, 580, 480);

        Texture2D cropped = new Texture2D(heightMap1.GraphicsDevice, area.Width, area.Height);
        Color[] data = new Color[heightMap1.Width * heightMap1.Height];
        Color[] cropData = new Color[cropped.Width * cropped.Height];

        heightMap1.GetData(data);

        int index = 0;


        for (int y = 0; y < area.Y + area.Height; y++) // for each row
        {

                for (int x = 0; x < area.X + area.Width; x++) // for each column 
                {
                    cropData[index] = data[x + (y * heightMap1.Width)];
                    index++;
                }

        }

    cropped.SetData(cropData);

Solution

  • Here is the code to crop a texture. Note that the GetData method can already select rectangular subsection of the image - there is no need to manually crop.

    // Get your texture
    Texture2D texture = Content.Load<Texture2D>("myTexture");
    
    // Calculate the cropped boundary
    Rectangle newBounds = texture.Bounds;
    const int resizeBy = 20;
    newBounds.X += resizeBy;
    newBounds.Y += resizeBy;
    newBounds.Width -= resizeBy * 2;
    newBounds.Height -= resizeBy * 2;
    
    // Create a new texture of the desired size
    Texture2D croppedTexture = new Texture2D(GraphicsDevice, newBounds.Width, newBounds.Height);
    
    // Copy the data from the cropped region into a buffer, then into the new texture
    Color[] data = new Color[newBounds.Width * newBounds.Height];
    texture.GetData(0, newBounds, data, 0, newBounds.Width * newBounds.Height);
    croppedTexture.SetData(data);
    

    Of course, keep in mind that SpriteBatch.Draw can take a sourceRectangle parameter, so you may not even need to copy the texture data around at all! Just use a subsection of the original texture. For example:

    spriteBatch.Draw(texture, Vector2.Zero, newBounds, Color.White);
    

    (Where newBounds is calculated in the same way as in the first code listing.)