English 中文(简体)
How to represent binary transparency?
原标题:

Lately I ve been interested in representing uncompressed bitmaps in memory. However, one thing I m not sure how to implement properly is binary transparency. E.g., I start out with something like this:

struct RGBPixel {
 uint8_t red;
 uint8_t green;
 uint8_t blue;
};

struct bitmap {
 struct RGBPixel *data;
 size_t width;
 size_t height;
 size_t bytesPerPixel;
 size_t bytewidth;
 /* etc. */
};

I suppose the simplest way would be this:

struct RGBPixel {
 uint8_t red;
 uint8_t green;
 uint8_t blue;
 bool transparent;
};

But that seems a bit wasteful (you might as well add a full alpha channel). The only other possibility I can think of is to reserve one of the colors as being transparent, but then you lose the ability to display that color. Is there a standard way to do this?

How do common formats (GIF, 8-bit PNG, etc.) represent this?

最佳回答

There are 16M colors, designating one of them as transparent will not be a big hardship. Unless your image is 16 megapixels, you can be sure it doesn t even use all 16M colors anyway, just pick one that isn t used and make it the transparency color. If you do have a huge image that uses them all, select the one that is least used and change it to an adjacent color, making it unused.

As you indicated, trying to store a single bit per pixel with the pixel RGB data isn t efficient. You should probably either store all the RGB pixels in one pointer and then a bitmap of the same H and V dimensions in another pointer, or you can do chroma keying. You could store the data with R,G,B and transparency bitmap separately as mentioned above but that s generally very inefficient when it comes to drawing it.

问题回答

Gif uses a specified color for transparent. (e.g.: lets say 0xFFFF00 is transparent, so all pixels with this color will be display as transparent.) This color could not be used in this image.
Png has an alpha channel, that means another int which represents the alpha value of the pixel. (e.g: 0 = fully transparent, 255 = opaque, 128 = half-transparent)

Commonly there is a fourth Alpha channel to represent transparency.

i.e. instead of RBG, you can have RGBA.

Binary transparency is also called Chroma Keying. You designate a colour as the transparent colour and in your drawing function draw a pixel if its colour is not the chroma key ( designated transparent colour).

Per pixel alpha is used when you do multi-level transparency such as drop shadows.

You could store the transparency in separate memory, or even store each channel separately, e.g.:

struct bitmap {
 uint8_t *red;
 uint8_t *green;
 uint8_t *blue;
 uint8_t *transparency;
 // or packed: uint8_t *RGB, *transparency;
 size_t width;
 size_t height;
};

Then allocate width*height / 8 bytes for the transparency channel, and assuming 8 bits per color channel you can access the bits like this:

bool get_transparency( struct bitmap* bmp, size_t x, size_t y ) {
  size_t idx = y * bmp->width + x;
  size_t tidx = idx >> 3; // = idx / 8
  uint8_t t8 = (uint8_t)( idx & 7 ); // = idx % 8
  uint8_t mask = 1 << t8;
  return ( bmp->transparency[tidx] & mask ) != 0;
}

Note, accessing the bits can be optimized, this is just an example.

Another solution: you could swipe a bit of one of the color channels, and define your struct like this:

struct RGBPixel {
 uint8_t red : 7;
 uint8_t transparency : 1;
 uint8_t green;
 uint8_g blue;
};

When storing or reading the red channel, you have to scale accordingly, e.g. red = (uint8_t)( ( (uint16_t)pix->red * 8 ) / 7 );





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签