Color conversion questions

Hi,

I want to use 32 bit bitmaps with a transparent color in my game. I’ve got
questions on several issues:

  • how is transparency represented in a 32 bit bitmap ? I mean can I use a
    specific pixel color to do this ? I don’t want to use alpha transparency
    because the screen pixel depth might not support alpha. or is there a
    work-around this ?

  • at the start of the game, 32 bit bitmaps should be converted to screen
    pixel depth (8,16 or 24 bits), right ? then how to make sure that the
    transparent ‘pixel’ is indeed transparent ? and how to construct a common
    optimized palette from all the 32 bit bitmaps ? And how to convert these 32
    bit bitmaps into the screen pixel depth so that the color index info
    corresponds to the common palette ?

Please advise on any other issue regarding using bitmaps with a single
transparent color in a game…This is my first game.

See ya,

  • Meetul Kinarivala

Look at the SDL_SetColorKey function, you can set the transparent pixel with
that, using SDL_MapRGB might help too. If your images are stored in a format
that supports the transparent pixel you could look at the SDL_image library
(http://www.libsdl.org/projects/SDL_image/index.html)
which I think will set the color key for you.On Wed, Oct 03, 2001 at 04:53:40PM -0700, Meetul Kinarivala wrote:

  • how is transparency represented in a 32 bit bitmap ? I mean can I use a
    specific pixel color to do this ? I don’t want to use alpha transparency
    because the screen pixel depth might not support alpha. or is there a
    work-around this ?


Adam
@Adam_Feakin
j: superpeach at jabber.org
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 240 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20011003/7e5f9d0c/attachment.pgp

Thanks for the tips, Adam. Right now I’m storing all images as 8 bit with
transparent pixel index 0. but the trouble is that whenever a new image is
introduced, I have to go back to macromedia fireworks to re-create a common
shared palette and export all images using that palette…

Since I don’t use alpha, I can store images as 24 bit JPEGs with color
(0,0,0) as transparent pixel… But then will I have to compute the shared
palette in real time and convert colors in real time, if the user’s os shell
is running on 8 or 16 bit palettized mode ?

Meetul> On Wed, Oct 03, 2001 at 04:53:40PM -0700, Meetul Kinarivala wrote:

  • how is transparency represented in a 32 bit bitmap ? I mean
    can I use a
    specific pixel color to do this ? I don’t want to use alpha transparency
    because the screen pixel depth might not support alpha. or is there a
    work-around this ?

Look at the SDL_SetColorKey function, you can set the transparent
pixel with
that, using SDL_MapRGB might help too. If your images are stored
in a format
that supports the transparent pixel you could look at the
SDL_image library
(http://www.libsdl.org/projects/SDL_image/index.html)
which I think will set the color key for you.

Adam
adamf at snika.uklinux.net
j: superpeach at jabber.org

Hi,

I want to use 32 bit bitmaps with a transparent color in my game. I’ve
got questions on several issues:

  • how is transparency represented in a 32 bit bitmap ?

Either using 8 bits as an alpha channel, or using a specific bit pattern
as color key, just as for any other pixel format.

I mean can I use a specific pixel color to do this ?

Yes. Use SDL_MapRGB() to translate from Uint8 R,G,B into whatever pixel
format you’re using.

I don’t want to use alpha
transparency because the screen pixel depth might not support alpha. or
is there a work-around this ?

Alpha has little to do with screen pixel format - it’s a "cross fade"
operation between the target pixel and the source pixel, controlled by
the source surface alpha, or the alpha field of the source pixel.

However, it can be a performance issue regardless of target pixel
format, unless you’re using hardware accelerated OpenGL. (SDL 2D alpha
blending is done in software, as most 2D APIs lack alpha blending
support.)

  • at the start of the game, 32 bit bitmaps should be converted to
    screen pixel depth (8,16 or 24 bits), right ?

Preferably, yes…

then how to make sure
that the transparent ‘pixel’ is indeed transparent ?

You should set up any colorkeying, alpha or whatever before you convert
the surfaces into screen format - or just use SDL_MapRGB() with the pixel
format struct of the surface you’re addressing, as always.

I think that SDL_MapRGB() translates your RGB values exactly the same
way as does the SDL surface conversion code, which would mean that
everything works even if conversion loses bits.

You have to be careful about “real” colors that are too close to the
colorkey, though. They may end up with the same pixel value as the
colorkey pixels - which is a perfect demonstration of why you should deal
with this stuff before converting anything to an “unknown” format, such
as the screen format.

(In the Kobo Deluxe/Project Spitfire engine, I have a filter plugin
system, and to keep things simple, the first filter just converts
everything into 32 bit RGBA, so the actual filters have a fixed format to
deal with, regardless of file formats. As an extra bonus, the
colorkey->alpha translation feature has a “fuzziness factor”, to deal
with the rounding errors that GIMP and PhotoShop introduce when
converting between pallettized and RGB modes.)

and how to
construct a common optimized palette from all the 32 bit bitmaps?

You don’t. Only 8 bit surfaces have palettes.

And
how to convert these 32 bit bitmaps into the screen pixel depth so that
the color index info corresponds to the common palette ?

This isn’t applicable to 32 bit surfaces; see above.

(Right, it applies to some extent if your screen format is 8 bit - but do
you really want to optimize your code specifically for that, if you’re
using 32 bit image data?)

Please advise on any other issue regarding using bitmaps with a single
transparent color in a game…This is my first game.

Well…

First, pick a key that’s as different as possible from the colors used in
your game. (That gives a “fuzziness factor” like the one in my engine a
better chance of working properly if you end up really needing it.)

Second, note that if you’re working with PhotoShop or GIMP, these
applications have two issues:
1) they can hardly do anything in indexed color mode, so you
have to convert to RGB to do anything interesting, and

2) when converting between indexed color and RGB modes, both
   introduce some kind of rounding errors that will break the
   "exact match" colorkey system used by SDL. (For example, the
   bright red colorkey of the Kobo Deluxe graphics turns from
   0xff0000 to 0xfe0000 after an indexed->RGB->indexed conversion.
   Older PhotoShop was *totally* broken, and ruined the whole
   image, just not the palette!)

Finally, think again about alpha blending. I’m using it for antialiazing
and some special effects in Kobo Deluxe, all over the place. (The logo,
the rounded frame and the font are always using it.) In fact, it’s
applied to every single sprite in 640x480+ resolutions, as a result of
the interpolated image scaling.

Disabling it doesn’t make a significant difference in performance, as
only the pixels that have alpha values other than 0 or 255 are affected.
The RLE encoding of SDL encodes surfaces so that “empty” pixels are
skipped, opaque pixels are copied, and only alpha blended pixels are
actually blended.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Thursday 04 October 2001 01:53, Meetul Kinarivala wrote:

okay here’s how I’ll approach…correct me if something’s missing or the
order is incorrect:

  • i’ll use 24 bit jpegs with flouroscent green(rare elsewhere) at points
    where I want transparency
  • use SDL_DisplayFormat(…) to convert a loaded 24 bit jpg to screen’s video
    format
  • use SDL_MapRGB(…) to find the pixel value of the fl. green color
  • use SDL_SetColorKey(…) to set the said pixel value as transparent
  • use SDL_BlitSurface(…) to blit the final surface…

and how to
construct a common optimized palette from all the 32 bit bitmaps?

You don’t. Only 8 bit surfaces have palettes.

Sure, but if the screen’s mode is 8 bit palettized and all images are say,
24 bit RGB computation of a common optimized palette is a part of converting
24 RGB to 8 palettized, right ?

Meetul

“Meetul Kinarivala” a ?crit dans le message news:
mailman.1002165481.17656.sdl at libsdl.org

okay here’s how I’ll approach…correct me if something’s missing or the
order is incorrect:

  • i’ll use 24 bit jpegs with flouroscent green(rare elsewhere) at points
    where I want transparency
  • use SDL_DisplayFormat(…) to convert a loaded 24 bit jpg to screen’s
    video
    format
  • use SDL_MapRGB(…) to find the pixel value of the fl. green color
  • use SDL_SetColorKey(…) to set the said pixel value as transparent
  • use SDL_BlitSurface(…) to blit the final surface…

A solution can be also to grab the color of a pixel from the images at a
location that is
always suppose to be transparent, let say in (0,0) (See SDL docs to have the
getpixel function) use SDL_MapRGB with the color found then SetColorKey
and BlitSurface.
This method could appears heavy, but by that way you can attritube any
color
as the colorKey, as long as the colorKey is the one at the same point
location
on all images (in the example (0,0).

 Simply.

and how to
construct a common optimized palette from all the 32 bit bitmaps?

You don’t. Only 8 bit surfaces have palettes.

Sure, but if the screen’s mode is 8 bit palettized and all images are say,
24 bit RGB computation of a common optimized palette is a part of
converting> 24 RGB to 8 palettized, right ?

Meetul

“Meetul Kinarivala” wrote:

  • how is transparency represented in a 32 bit bitmap ? I mean can I use a
    specific pixel color to do this ? I don’t want to use alpha transparency
    because the screen pixel depth might not support alpha. or is there a
    work-around this ?

either use a specific pixel value for it or use alpha anyway; SDL supports
RLE-encoded surfaces with alpha channel for fast blitting onto 15, 16 and
32bpp destinations. As a bonus, you get full alpha blending, only paying
the performance cost for the pixels where you use it

  • at the start of the game, 32 bit bitmaps should be converted to screen
    pixel depth (8,16 or 24 bits), right ? then how to make sure that the
    transparent ‘pixel’ is indeed transparent

there is no perfect solution, since two distinct 24-bit colours may
map to the same pixel value in shallower formats. One way is to make
the colour key distinct enough using a colour that’s unlikely to be
used elsewhere (a common choice is saturated magenta, #ff00ff).

Even this may clash in 8bpp, but since SDL’s pixel format converter is
written for speed rather than quality, images converted to 8bpp may look
rather ugly. For this reason you may want to write your own converter
to 8bpp (I suggest an ordered dither, or a Floyd-Steinberg dither for
sprites that aren’t animated), where you can recognise the colour key
(or transparent alpha value) of your sprite and substitute the right value.
Or you could do this ahead of time, using your favourite image processing
tool for it

and how to construct a common
optimized palette from all the 32 bit bitmaps ? And how to convert these 32
bit bitmaps into the screen pixel depth so that the color index info
corresponds to the common palette ?

there are specialised tools to construct a common palette. You could
make a big picture of all your images and then just convert it
to 8bpp and use the resulting. Or you could just pick a generic palette
(like the Netscape 6x6x6 colour cube) and add some shades you think are
missing

Under Unix, the free image processing tools every game developer
should have include Gimp, ImageMagick, and the NetPBM tools. For
MacOS and Win32, Photoshop is extremely good (if you can afford it), but
there are a lot of other tools as well

okay, once I have the common palette created, using some tool, how do I
convert the 32 bit surfaces that I load in the game to 8 bit surfaces while
mapping RGB pixels to their right index into the common palette ? Can SDL do
this, or where can I find the an algorithm ? or the most optimized algorithm
would be ‘closest distance’ algo ?

Meetul> there are specialised tools to construct a common palette. You could

make a big picture of all your images and then just convert it
to 8bpp and use the resulting. Or you could just pick a generic palette
(like the Netscape 6x6x6 colour cube) and add some shades you think are
missing

“Meetul Kinarivala” wrote:

okay, once I have the common palette created, using some tool, how do I
convert the 32 bit surfaces that I load in the game to 8 bit surfaces while
mapping RGB pixels to their right index into the common palette

do a web search on “dithering”, or look it up in your favourite computer
graphics textbook. Look for “ordered dither” and “Floyd-Steinberg”

okay here’s how I’ll approach…correct me if something’s missing or the
order is incorrect:

  • i’ll use 24 bit jpegs with flouroscent green(rare elsewhere) at
    points where I want transparency

Beware of jpeg compression artifacts, though - jpeg compresses chroma
harder than luminosity, so you lose your exact colors very quickly.
Either use a “clean” function like the one I have in Kobo Deluxe, or
(preferably) use PNG - which also supports alpha channel, BTW.

  • use SDL_DisplayFormat(…) to convert a loaded 24 bit jpg to screen’s
    video format

Actually, I think it’s better to do display format conversion last. (At
least, something I read in the docs made me change the Kobo code to do it
that way - which just happened to also work better with the processing
"plugin" system.)

  • use SDL_MapRGB(…) to find the pixel value of the fl. green color
  • use SDL_SetColorKey(…) to set the said pixel value as transparent

Yes. (Although see above, regarding matching the colorkey.)

  • use SDL_BlitSurface(…) to blit the final surface…

and how to
construct a common optimized palette from all the 32 bit bitmaps?

You don’t. Only 8 bit surfaces have palettes.

Sure, but if the screen’s mode is 8 bit palettized and all images are
say, 24 bit RGB computation of a common optimized palette is a part of
converting 24 RGB to 8 palettized, right ?

Yes. (See other posts on how to construct a suitable palette, and how to
do a better conversion than the speed optimized SDL code does.)

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Thursday 04 October 2001 05:15, Meetul Kinarivala wrote:

You should call SDL_SetColorKey before SDL_DisplayFormatOn Wed, Oct 03, 2001 at 08:15:52PM -0700, Meetul Kinarivala wrote:

  • i’ll use 24 bit jpegs with flouroscent green(rare elsewhere) at points
    where I want transparency
  • use SDL_DisplayFormat(…) to convert a loaded 24 bit jpg to screen’s video
    format
  • use SDL_MapRGB(…) to find the pixel value of the fl. green color
  • use SDL_SetColorKey(…) to set the said pixel value as transparent
  • use SDL_BlitSurface(…) to blit the final surface…

    Martin

    Bother! I didn’t think you had the lobes! --Quark.

Hello Meetul,

MK> - i’ll use 24 bit jpegs with flouroscent green(rare elsewhere) at points
MK> where I want transparency

Unless you are planning on compressing with no loss at all, don’t use
JPG. JPEG works on using an 8x8 quantisation method and as such you
can’t guarantee that your florescent green will always be the exact
same colour - especially around the edges of whatever you want to
actually show. I assume it’s a sprite. You’ll likely get some really
nasty effects around the edges of your sprites if you do that.

MK> - use SDL_MapRGB(…) to find the pixel value of the fl. green color

This is why you shouldn’t use JPG, the colour you find may not be the
same colour across the whole image! Use something non-lossy. Does
SDL_Image support PNG? If so, try that, it’s non-lossy and compresses
very well. Essentially a BMP but zipped up.

Neil.

Hello Meetul,

MK> - i’ll use 24 bit jpegs with flouroscent green(rare elsewhere) at
points MK> where I want transparency

Unless you are planning on compressing with no loss at all, don’t use
JPG. JPEG works on using an 8x8 quantisation method and as such you
can’t guarantee that your florescent green will always be the exact
same colour - especially around the edges of whatever you want to
actually show. I assume it’s a sprite. You’ll likely get some really
nasty effects around the edges of your sprites if you do that.

MK> - use SDL_MapRGB(…) to find the pixel value of the fl. green color

This is why you shouldn’t use JPG, the colour you find may not be the
same colour across the whole image! Use something non-lossy. Does
SDL_Image support PNG?

Yes - and indeed, it works great, with or without alpha channel. Also
compresses many times better, nondestructively, than does jpg at
"highest quality".

If so, try that, it’s non-lossy and compresses
very well. Essentially a BMP but zipped up.

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Thursday 04 October 2001 17:31, Neil Griffiths wrote:

Thanks Nishal, David, Neil, Martin, Mattias, Billie and all, for all the
nice help :slight_smile:
-Meetul