How to get a pixel from a surface?

Started by
18 comments, last by s_cloudx 22 years, 1 month ago
Hmm. GetRValue, GetGValue and GetBValue doesn''t seem to work . I know that a certain pixel (e.g. 12,20) has a pixel of:

red-10
green-243
blue-0

yet, I seem to be getting wrong result. Can anyone help me?
--------------------------Sony "Mr. Valdez" ValdezPinoyforum.net Technical EditorPinoyforum.net - the breeding ground of the Filipino Computer Talents
Advertisement
For non time critical stuff use GDI.

For ingame stuff use Lock(). Look it up in the DX docs.
-------------Ban KalvinB !
quote:Original post by s_cloudx
Hmm. GetRValue, GetGValue and GetBValue doesn''t seem to work . I know that a certain pixel (e.g. 12,20) has a pixel of:

red-10
green-243
blue-0

yet, I seem to be getting wrong result. Can anyone help me?


If your prog is running in, say, 16bit colour, it''ll have to convert to get your the 32bit COLORREF containing 8bit values. A full white pixel in 16bit mode might contain (248, 252, 248) in 32bit mode.


Kippesoep
Maybe I should had been more specific.

On photoshop, I check the color of a pixel location (eg. 12,20). Photoshop says it has a color of

red-10
green-243
blue-0

But I get mixed result when I try to get the color. Can someone give me a code on how to get the right color, pls?
--------------------------Sony "Mr. Valdez" ValdezPinoyforum.net Technical EditorPinoyforum.net - the breeding ground of the Filipino Computer Talents
typedef union
{
struct
{
BYTE b;
BYTE g;
BYTE r;
} rgb;

struct
{
BYTE r;
BYTE g;
BYTE b;
} bgr;
} TRIPLE, *LPTRIPLE;

LPWORD pWord;
LPTRIPLE pTriple;
LPDWORD pDword;
DWORD dwColor, dwRed, dwGreen, dwBlue;

hr = m_pBackSurface->Lock(NULL, &ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL);

// 16 bits
pWord = (LPWORD)ddsd.lpSurface + ((ddsd.lPitch / 2) * y) + x;
dwColor = (DWORD)(*pWord);

// 24 bits
pTriple = (LPTRIPLE)ddsd.lpSurface + ((ddsd.lPitch / 3) * y) + x;
dwRed = (DWORD)pTriple->rgb.r;
dwGreen = (DWORD)pTriple->rgb.g;
dwBlue = (DWORD)pTriple->rgb.b;
dwColor = (dwRed << 16) | (dwGreen << 8) | (dwBlue);
// or
dwRed = (DWORD)pTriple->bgr.r;
dwGreen = (DWORD)pTriple->bgr.g;
dwBlue = (DWORD)pTriple->bgr.b;
dwColor = (dwRed) | (dwGreen << 8) | (dwBlue << 16);

// 32 bits
pDword = (LPDWORD)ddsd.lpSurface + ((ddsd.lPitch / 4) * y) + x;
dwColor = (DWORD)(*pDword);

hr = m_pBackSurface->Unlock(NULL);


Made In Taiwan
Anon: I might be missing something, but how can I extract the RGB in 16-bit color? I''ll see later when I get home and try your code.
--------------------------Sony "Mr. Valdez" ValdezPinoyforum.net Technical EditorPinoyforum.net - the breeding ground of the Filipino Computer Talents

// 16 bits
pWord = (LPWORD)ddsd.lpSurface + ((ddsd.lPitch / 2) * y) + x;
wColor = *pWord;

// 16 bits R5G5B5
wRed = (wColor & 0x7C00) >> 10;
wGreen = (wColor & 0x03E0) >> 5;
wBlue = (wColor & 0x001F);

// 16 bits R5G6B5
wRed = (wColor & 0xF800) >> 11;
wGreen = (wColor & 0x07E0) >> 5;
wBlue = (wColor & 0x001F);

Made In Taiwan
Anon, it still doesn''t work

Using your code, I get:

R - 15
G - 30
B - 8


I''m expecting (i checked the color with photoshop):

R - 248
G - 240
B - 64

or, am I missing something? my guess would be that I''m getting the correct colors information but photoshop is giving me a different color format.

Kippesoep, I believed you were right. Maybe what I really need right now is to convert 16bit (or even 32bit) to 8bit. So, how do I do that?
--------------------------Sony "Mr. Valdez" ValdezPinoyforum.net Technical EditorPinoyforum.net - the breeding ground of the Filipino Computer Talents
I''ll just throw a little something in here.
A little re-write of what I use in my 16 bit sprite library.


  USHORT *surf_ptr;USHORT colour;DDSURFACEDESC2  ddsd;ddsd.dwSize = sizeof(ddsd);if ( surface == NULL )     return;  // let''s get some surface info  surface -> GetSurfaceDesc( &ddsd );    ( surface ) -> Lock( NULL,                       &ddsd,                       DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,                       NULL);   surf_ptr = (USHORT *)ddsd.lpSurface;  ( surface ) -> Unlock(NULL);  colour = *(surf_ptr + ( y * ddsd.dwWidth ) + x );  


Then extract colours using AP''s equations.
This assumes surface is made in system memory.

Guy


"Who lives in a pineapple under the sea ?"
quote:Original post by s_cloudx
or, am I missing something? my guess would be that I'm getting the correct colors information but photoshop is giving me a different color format.

Kippesoep, I believed you were right. Maybe what I really need right now is to convert 16bit (or even 32bit) to 8bit. So, how do I do that?


You're getting a different range. There are two ways to convert: the fast way and the accurate way.
First, the fast way:
16bit R5G5B5finalRed = wRed << 3;finalGreen = wGreen << 3;finalBlue = wBlue << 3;16bit R5G6B5finalRed = wRed << 3;finalGreen = wGreen << 2;finalBlue = wBlue << 3;  


The accurate way:
16bit R5G5B5finalRed = wRed * 255 / 31;finalGreen = wGreen * 255 / 31;finalBlue = wBlue * 255 / 31;16bit R5G6B5finalRed = wRed * 255 / 31;finalGreen = wGreen * 255 / 63;finalBlue = wBlue * 255 / 63;  


You could speed that up using two lookup tables (a total of 96 bytes):

    unsigned char table5bit [32];unsigned char table6bit [64];void initTables (){    int i;    for (i = 0; i < 32; i++) table5bit [i] = (unsigned char)(i * 255 / 31);    for (i = 0; i < 64; i++) table6bit [i] = (unsigned char)(i * 255 / 63);}    


16bit R5G5B5finalRed = table5bit [wRed];finalGreen = table5bit [wGreen];finalBlue = table5bit [wBlue];16bit R5G6B5finalRed = table5bit [wRed];finalGreen = table6bit [wGreen];finalBlue = table5bit [wBlue];  





[edited by - Kippesoep on March 15, 2002 1:27:16 PM]
Kippesoep

This topic is closed to new replies.

Advertisement