Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

share|improve this question

migrated from stackoverflow.com Aug 25 '11 at 14:41

This question came from our site for professional and enthusiast programmers.

    
Have you set the texture with the correct surface format? –  George Duckett Aug 25 '11 at 6:58
    
I don't really know, how do i check it? –  Bjørn Moholt Aug 25 '11 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). –  George Duckett Aug 25 '11 at 14:18

1 Answer 1

up vote 2 down vote accepted

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.

share|improve this answer
    
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 –  Bjørn Moholt Aug 25 '11 at 15:57
    
I'll dig into it more when I get home, and can crack open ilspy –  Joe Aug 25 '11 at 16:01
    
Probably should be: animation.GetData<Color>(0,new Rectangle(0,0,1,1), animationData, 0, animationData.Length); –  Tomas Voracek Aug 25 '11 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. –  Joe Aug 25 '11 at 21:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.