# XNA: Texture2D.GetData runtime error

I am trying to get the colors of the top left pixel in an image, I use this code:

 using (FileStream stream = File.OpenRead(animationFile))
{
animation = Texture2D.FromStream(graphicsDevice, stream);
}

Color[] animationData = new Color[1];
animation.GetData<Color>(animationData, 0, 1);


When i run it I get an System.Argument exception saying: The date passed in is too large or too small for this resource"

Anyone know what I'm doing wrong?

Edit: Added code where i load the texture, I have also tried using the Content.Load method, but the result was the same.

• Have you set the texture with the correct surface format? Aug 25, 2011 at 6:58
• I don't really know, how do i check it?
– Bjørn Moholt
Aug 25, 2011 at 14:16
• Edit your question to include the code where you create the texture. It should be created with something like SurfaceFormat.Color (from memory). Aug 25, 2011 at 14:18

## 1 Answer

I don't know why that error is getting thrown, but here is a solutions that works.

Color[] animationData  = new Color[1];
animation.GetData<Color>(0,new Rectangle(0,0,1,1),c, 0, 1);


We are creating a 1x1 rectangle, and only sampling data from that.

update

Ok, I have had some time you look into this more, and I think there may be a bug in the framework. When you are doing Texture2D.GetData<T>(T[] data, int start, int length) it is just an overload for Texture2D.GetData<T>(int level, Rectangle? rect, T[] data, int start, int length) and passes in null for the rectangle. If you manually do that (ie. pass in null instead of the 1x1 rectangle) you get the same error.

Now, follow the chain down, and it eventually calls

private unsafe void CopyData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount,...)


This method is way to long to post here (over 220 lines of code in ILSpy), and since I don't have the whole picture it is hard to figure out. However, this little bit is interesting.

tagRECT* ptr2 = null;
Rectangle rectangle = default(Rectangle);
if (rect.HasValue)
{
rectangle = rect.Value;
ptr2 = ref rectangle;
if (ptr2 != null)
{
*(int*)(ptr2 + 8 / sizeof(tagRECT)) = *(int*)(ptr2 + 8 / sizeof(tagRECT)) + *(int*)ptr2;
*(int*)(ptr2 + 12 / sizeof(tagRECT)) = *(int*)(ptr2 + 12 / sizeof(tagRECT)) + *(int*)(ptr2 + 4 / sizeof(tagRECT));
}
}


See how ptr2 is only defined if you passed in a value for the rectangle? Further down the trail (if I followed the correct code path)

num5 = <Module>.D3DXLoadSurfaceFromSurface(ptr3, null, (tagRECT*)ptr2, ptr5, null, (tagRECT*)ptr2, 1, 0);


and then later we are doing some recursion based on if num5>=0. Which recursive cal is actually determined on some other logic I haven't worked out, but I don't think that part matters...famous last words, right? :)

So all that to say this, I don't think that the Rectangle passed is is supposed to be null. A few places in the code it looks like they are trying to force the rectangle to have a value of the texture size. Perhaps it isn't working.

Take all of that with several grains of salt. I am in not way qualified as a low level GFX programmer. Maybe someone else here can answer for certain.

• Thanks, that worked, however I have no clue why, i thought i did the same thing, telling it to take only one pixel, but i guess I didn't :D Aug 25, 2011 at 15:57
• I'll dig into it more when I get home, and can crack open ilspy
– user159
Aug 25, 2011 at 16:01
• Probably should be: animation.GetData<Color>(0,new Rectangle(0,0,1,1), animationData, 0, animationData.Length); Aug 25, 2011 at 20:27
• yeah, but that doesn't add much value. if animation data was larger than 1 it would throw an error because you would be requesting more data than you specified in the rectangle. If you are going to do that you need to do new Rectangle(0,0,animationdata.Length,animationData.Length) this will, of course, sample more data than you need, but it is the safe approach.
– user159
Aug 25, 2011 at 21:19