From: John Ratliff on
When creating a wxBitmap from a wxImage, what is the color order of the
image data?

It seems to be backwards from what I would expect.

I have an array of 24-bit RGB data (size = width * height * 3). However,
when I convert this to a bitmap and blit it to a wxPanel, I get the
color order which suggests a BGR mapping.

My pixmap (640x480) is created like this:

int tick = SDL_GetTicks();

for (int y = 0; y < 480; y++) {
for (int x = 0; x < 640; x++) {
wxUint32 color = (y * y) + (x * x) + tick;
wxUint8 *pixels = static_cast<wxUint8 *>(screen->pixels) +
(y * screen->pitch) + (x * 3);

pixels[0] = color & 0xFF;
pixels[1] = (color >> 8) & 0xFF;
pixels[2] = (color >> 16) & 0xFF;
}
}

Then in my OnPaint() callback, I create the bmp and blit it like this:

wxBitmap bmp(wxImage(screen->w, screen->h,
static_cast<unsigned char *>(screen->pixels), true));
wxBufferedPaintDC dc(this, bmp);

The image on the screen is extremely red, even though the values I'm
producing put the red component between 0 and 6. The blue and green
components span the spectrum, but red is never present in any
significant amount.

Can the wxBitmap constructor produce a wxBitmap from an RGB ordered
image, or should I just use BGR? It's not necessarily a problem to use
BGR, it's just weird and I'd prefer to use RGB if possible.

My complete (compilable) code is at
http://code.technoplaza.net/temp/wx-sdl.cc

But it's ~500 lines, so I didn't want to post it here unnecessarily.

Thanks,

--John Ratliff
From: Paul Koning on
>>>>> "John" == John Ratliff <user(a)example.net> writes:

John> When creating a wxBitmap from a wxImage, what is the color
John> order of the image data?

John> It seems to be backwards from what I would expect.

Hm. The doc very clearly says RGB -- in the description of
GetData(). It doesn't say for the case of the constructor, but the
only sane assumption is that it applies there as well.

I've used the wxImage constructor with pixmap data (without the fourth
argument, but that shouldn't matter) and it does RGB correctly -- both
on Mac (big endian) and PC (little endian) platforms.

John> I have an array of 24-bit RGB data (size = width * height *
John> 3). However, when I convert this to a bitmap and blit it to a
John> wxPanel, I get the color order which suggests a BGR mapping.

John> My pixmap (640x480) is created like this:

John> int tick = SDL_GetTicks();

John> for (int y = 0; y < 480; y++) { for (int x = 0; x < 640; x++) {
John> wxUint32 color = (y * y) + (x * x) + tick; wxUint8 *pixels =
John> static_cast<wxUint8 *>(screen->pixels) + (y * screen->pitch) +
John> (x * 3);

John> pixels[0] = color & 0xFF; pixels[1] = (color >> 8) & 0xFF;
John> pixels[2] = (color >> 16) & 0xFF; } }

John> Then in my OnPaint() callback, I create the bmp and blit it
John> like this:

John> wxBitmap bmp(wxImage(screen->w, screen->h, static_cast<unsigned
John> char *>(screen->pixels), true)); wxBufferedPaintDC dc(this,
John> bmp);

John> The image on the screen is extremely red, even though the
John> values I'm producing put the red component between 0 and 6. The
John> blue and green components span the spectrum, but red is never
John> present in any significant amount.

I'm confused. Your code basically calculates a value which is the
square of the distance from (0,0) and uses that to produce the
colors. The low order 8 bits of that are R, the next 8 are G, and the
upper 8 are B. My calculator says that you're producing all R and G
values and values 0 through 9 for B.

paul


---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-unsubscribe(a)lists.wxwidgets.org
For additional commands, e-mail: wx-users-help(a)lists.wxwidgets.org

From: John Ratliff on
> John> int tick = SDL_GetTicks();
>
> John> for (int y = 0; y < 480; y++) { for (int x = 0; x < 640; x++) {
> John> wxUint32 color = (y * y) + (x * x) + tick; wxUint8 *pixels =
> John> static_cast<wxUint8 *>(screen->pixels) + (y * screen->pitch) +
> John> (x * 3);
>
> John> pixels[0] = color & 0xFF; pixels[1] = (color >> 8) & 0xFF;
> John> pixels[2] = (color >> 16) & 0xFF; } }
>
> John> Then in my OnPaint() callback, I create the bmp and blit it
> John> like this:
>
> John> wxBitmap bmp(wxImage(screen->w, screen->h, static_cast<unsigned
> John> char *>(screen->pixels), true)); wxBufferedPaintDC dc(this,
> John> bmp);
>
> John> The image on the screen is extremely red, even though the
> John> values I'm producing put the red component between 0 and 6. The
> John> blue and green components span the spectrum, but red is never
> John> present in any significant amount.
>
> I'm confused. Your code basically calculates a value which is the
> square of the distance from (0,0) and uses that to produce the
> colors. The low order 8 bits of that are R, the next 8 are G, and the
> upper 8 are B. My calculator says that you're producing all R and G
> values and values 0 through 9 for B.
>
> paul
>

Perhaps my thinking is backwards.

I'm thinking the red mask should be 0xFF0000, green mask 0xFF00, and
blue mask is 0xFF. alpha mask being 0xFF000000 (not that I need that --
it's always zero anyway). In other words, I'm expecting 32-bit data in
the form AARRGGBB.

Are you saying my red mask is actually 0xFF, green 0xFF00, and blue
0xFF0000 making it AABBGGRR?

Here are some sample values in hex (spaced by component):

color = 00 06 01 33
color = 00 00 92 6F
color = 00 01 00 AF
color = 00 02 00 33
color = 00 03 00 50
color = 00 04 00 13
color = 00 05 01 48
color = 00 06 02 A8
color = 00 03 8A 17
color = 00 04 00 5B
color = 00 05 01 7B
color = 00 06 01 5B
color = 00 07 02 E0
color = 00 08 01 60
color = 00 09 03 A8

Blue, which I think should represent the first 8 bits is all over the
spectrum. Green fluctuates, but not nearly as much as blue. Red, which I
think should be the bits 16-24, varies from 0-9.

If the map is ARGB, then the image should be blue. If the map is ABGR,
then it should be red.

The reason I think red is wrong is because the same image generating
program in SDL using a SDL_Surface directly mapped to a window is blue.
I would think the reason for this is that wxBitmap conversion is
ordering ABGR. But it doesn't say this.

You can see the original SDL program at
http://sol.gfxile.net/gp/ch02.html. There's even a win32 binary showing
it in blue. The original program uses 32-bit surface, but even when
converted to 24-bit drawing, it's still blue.

--John Ratliff
From: Paul Koning on
>>>>> "John" == John Ratliff <user(a)example.net> writes:

John> int tick = SDL_GetTicks();
>>
John> for (int y = 0; y < 480; y++) { for (int x = 0; x < 640; x++) {
John> wxUint32 color = (y * y) + (x * x) + tick; wxUint8 *pixels =
John> static_cast<wxUint8 *>(screen->pixels) + (y * screen->pitch) +
John> (x * 3);
>>
John> pixels[0] = color & 0xFF; pixels[1] = (color >> 8) & 0xFF;
John> pixels[2] = (color >> 16) & 0xFF; } }
>>
John> Then in my OnPaint() callback, I create the bmp and blit it
John> like this:
>>
John> wxBitmap bmp(wxImage(screen->w, screen->h, static_cast<unsigned
John> char *>(screen->pixels), true)); wxBufferedPaintDC dc(this,
John> bmp);
>>
John> The image on the screen is extremely red, even though the
John> values I'm producing put the red component between 0 and 6. The
John> blue and green components span the spectrum, but red is never
John> present in any significant amount.
>> I'm confused. Your code basically calculates a value which is the
>> square of the distance from (0,0) and uses that to produce the
>> colors. The low order 8 bits of that are R, the next 8 are G, and
>> the upper 8 are B. My calculator says that you're producing all R
>> and G values and values 0 through 9 for B.
>>
>> paul
>>

John> Perhaps my thinking is backwards.

John> I'm thinking the red mask should be 0xFF0000, green mask
John> 0xFF00, and blue mask is 0xFF. alpha mask being 0xFF000000 (not
John> that I need that -- it's always zero anyway). In other words,
John> I'm expecting 32-bit data in the form AARRGGBB.

John> Are you saying my red mask is actually 0xFF, green 0xFF00, and
John> blue 0xFF0000 making it AABBGGRR?

That's what you wrote.

Your code says "pixels[0] = color & 0xFF;". The wxImage order is RGB,
so pixels[0] is the red pixel.

paul


---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-unsubscribe(a)lists.wxwidgets.org
For additional commands, e-mail: wx-users-help(a)lists.wxwidgets.org

From: John Ratliff on
> John> Perhaps my thinking is backwards.
>
> John> I'm thinking the red mask should be 0xFF0000, green mask
> John> 0xFF00, and blue mask is 0xFF. alpha mask being 0xFF000000 (not
> John> that I need that -- it's always zero anyway). In other words,
> John> I'm expecting 32-bit data in the form AARRGGBB.
>
> John> Are you saying my red mask is actually 0xFF, green 0xFF00, and
> John> blue 0xFF0000 making it AABBGGRR?
>
> That's what you wrote.
>
> Your code says "pixels[0] = color & 0xFF;". The wxImage order is RGB,
> so pixels[0] is the red pixel.
>

I put the blue value in the red pixel... I can't believe I didn't see
that...

Thanks,

--John Ratliff