# [XNA] Texture2D Crop

This topic is 2299 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I need some kind of formula to crop down a Texture2D. The textures are not loading as assets nor saved to jpeg or png at any point, they're created on the fly by the game.

to

Not all of the white needs to be removed, just minimized down until the black shape is touched by the edges.

I'm thinking it would look something like (but not necessarily exact)

Texture2D Crop(Color excess)
{
// Forumula for cropping
return resultingTexture;
}

I was thinking maybe something with a Color[] but I couldn't think of way to make that work. Edited by Ghost Clock

##### Share on other sites
So XNA will let you load the color[] data from a texture2D object with Texture2D.GetData(), and through the Width and Height properties of the object, you have the dimensions handy. It's not the most efficient algorithm, but you could loop through rows first, then columns, determining at what index in the row/column the color shifts over the "culling" threshold (i.e. coming form the left, which index is the first to switch from white to black, and then what's the index from black back to white). Store the biggest index ranges across all rows and columns (which will give you the smallest dimensions that still contain your 'good' pixels), and then copy in the relevant data to a new, smaller color[] with the dimensions you just calculated. (System.Array has handy methods for copying select ranges of data).

##### Share on other sites
You can use Texture2D.GetData to get a Color[] representation of the texture. Are you generating these images on the GPU? Because if the images are created on the CPU, you don't have to get the data in the first place.

 Texture2D Crop(Color[] data, int width, int height, Color excess) { int x1 = width, x2 = 0, y1 = height, y2 = 0; for (int i = 0; i < width * height; i++) { if (data != excess) { int y = i / width; int x = i % width; x1 = Math.Min(x, x1); x2 = Math.Max(x, x2); y1 = Math.Min(y, y1); y2 = Math.Max(y, y2); } } Rectangle cropped = new Rectangle(x1, y1, x2 - x1 + 1, y2 - y1 + 1); Color[] newData = new Color[cropped.Width * cropped.Height]; for (int y = 0; y < cropped.Height; y++) { for (int x = 0; x < cropped.Width; x++) { int newIndex = y * cropped.Width + x; int oldIndex = (y + cropped.Y) * width + (x + cropped.X); newData[newIndex] = data[oldIndex]; } } Texture2D texture = new Texture2D(this.GraphicsDevice, cropped.Width, cropped.Height); texture.SetData(newData); return texture; }  Edited by lwm

##### Share on other sites

You can use Texture2D.GetData to get a Color[] representation of the texture. Are you generating these images on the GPU? Because if the images are created on the CPU, you don't have to get the data in the first place.

 //some slick stuff here 

Yes, like that! What I meant, only much cleaner and more efficient Describing algorithms is much easier if you just show someone the actual code...

##### Share on other sites
[quote name='lwm' timestamp='1346164394' post='4974124'][/quote]
First off, thank you. This is definitely a good start. Here's the issues. Trying your code directly in a new project (1 update call, crop, exit, save as), my first image in the first post results in this.

This happens to be the most dramatic example so far. Other examples show me getting the bottom and right edges cut off 1 row too much. I'm going to look at the math and see if I can't pin this down, if anyone else would take a look I'd appreciate it too.

Thanks again, I think this is really really close to what I need.

##### Share on other sites
Ha, I knew I shouldn't have used the Rectangle. I fixed the code in my previous post.

##### Share on other sites

Ha, I knew I shouldn't have used the Rectangle. I fixed the code in my previous post.

Dead on accurate. Thank you, this method will get plenty of usage.

1. 1
2. 2
3. 3
Rutin
15
4. 4
5. 5

• 13
• 26
• 10
• 11
• 9
• ### Forum Statistics

• Total Topics
633729
• Total Posts
3013578
×