Jump to content
  • Advertisement
Sign in to follow this  
Ghost Clock

[XNA] Texture2D Crop

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

If you intended to correct an error in the post then please contact us.

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.
ex1q.png
to
ex2f.png

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.
ex3vc.png
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 this post


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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!