Directx 9 c++ getting colours of pixels from a texture
Hi I would like to get all the pixel colours of a texture / surface somehow without using a GDI function like GetPixel(). Is this possible?
I searched on msdn and there is a way to lock a surface, can I use this to somehow get the pixels from my texture?
thanks,
r_bewick
This is XNA 3.0/C# but you should be able to do something similar.
private Rectangle zone;
Texture2D tex;
Color[] imgData = new Color[zone.Height * zone.Width];
tex.GetData<Color>(0, zone, imgData, 0, imgData.Length);
The rectangle can represent the entire texture or a subset for cropping.
private Rectangle zone;
Texture2D tex;
Color[] imgData = new Color[zone.Height * zone.Width];
tex.GetData<Color>(0, zone, imgData, 0, imgData.Length);
The rectangle can represent the entire texture or a subset for cropping.
Its a bit different in native code. Something like:
If that is successful it returns a structure 'locked' that contains info about the texture. You can now obtain a pointer that points to the colour in the top left of the image:
Now you have a pointer to all the data, you need to interpret it as colours. If you know it is a 32 bit format you can extract the data by going along the horizontal (x coordinate) reading the values 4 bytes at a time. One gotcha is that a line of data in memory may be longer than the width of the image - this is due to padding for optimisation purposes. So the memory width of a line may actually be different than the image width. You can find it though by looking at locked.Pitch, so:
And that's it. Once you have finished you must unlock the texture:
D3DLOCKED_RECT locked;HRESULT hr=texture->LockRect(0,&locked,NULL,0);
If that is successful it returns a structure 'locked' that contains info about the texture. You can now obtain a pointer that points to the colour in the top left of the image:
BYTE *bytePointer=(BYTE*)locked.pBits;
Now you have a pointer to all the data, you need to interpret it as colours. If you know it is a 32 bit format you can extract the data by going along the horizontal (x coordinate) reading the values 4 bytes at a time. One gotcha is that a line of data in memory may be longer than the width of the image - this is due to padding for optimisation purposes. So the memory width of a line may actually be different than the image width. You can find it though by looking at locked.Pitch, so:
for (DWORD y=0;y<surfaceDesc.Height;y++){ for (DWORD x=0;x<surfaceDesc.Width;x++) { DWORD index=(x*4+(y*(locked.Pitch))); // Blue BYTE b=bytePointer[index]; // Green BYTE g=bytePointer[index+1]; // Red BYTE r=bytePointer[index+2]; // Alpha BYTE a=bytePointer[index+3]; }}
And that's it. Once you have finished you must unlock the texture:
texture->UnlockRect(0);
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement