如何表示二进制透明度?

时间:2009-11-28 15:02:46

标签: c png bitmap transparency gif

最近我一直对在内存中表示未压缩的位图感兴趣。但是,我不确定如何正确实现的一件事是二元透明度。例如,我从这样的事情开始:

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. */
};

我想最简单的方法就是:

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

但这似乎有点浪费(你可以添加一个完整的alpha通道)。我能想到的唯一另一种可能性是保留其中一种颜色为透明,但是你失去了显示这种颜色的能力。有没有标准的方法来做到这一点?

常见格式(GIF,8位PNG等)如何表示这一点?

5 个答案:

答案 0 :(得分:1)

Gif使用指定的颜色进行透明。 (例如:假设0xFFFF00是透明的,因此具有此颜色的所有像素将显示为透明。)此颜色无法在此图像中使用。
Png有一个alpha通道,这意味着另一个int表示像素的alpha值。 (例如:0 =完全透明,255 =不透明,128 =半透明)

答案 1 :(得分:1)

有16M颜色,指定其中一个透明不会是一个很大的困难。除非您的图像是1600万像素,否则您可以确定它甚至不使用所有16​​M颜色,只需选择一个未使用的颜色并使其成为透明色。如果您确实有一个使用它们的巨大图像,请选择最少使用的图像并将其更改为相邻颜色,使其未使用。

如您所述,尝试使用像素RGB数据存储每个像素的单个位效率不高。您应该将所有RGB像素存储在一个指针中,然后在另一个指针中存储相同H和V维度的位图,或者您可以进行色度键控。如上所述,您可以分别使用R,G,B和透明度位图存储数据,但在绘制时通常效率非常低。

答案 2 :(得分:0)

通常有第四个Alpha通道来表示透明度。

即。而不是RBG,你可以有RGBA。

答案 3 :(得分:0)

二进制透明度也称为色度键控。您将颜色指定为透明颜色,如果颜色不是色度键(指定透明色),则在绘图功能中绘制像素。

当您执行多级透明度(如阴影)时,将使用每像素alpha。

答案 4 :(得分:0)

您可以将透明度存储在单独的存储器中,甚至可以单独存储每个通道,例如:

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;
};

然后为透明度通道分配width*height / 8个字节,假设每个颜色通道有8个位,您可以访问这样的位:

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;
}

注意,可以优化访问位,这只是一个例子。

另一个解决方案:您可以滑动其中一个颜色通道,并像这样定义您的结构:

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

存储或阅读红色通道时,您必须相应地进行缩放,例如red = (uint8_t)( ( (uint16_t)pix->red * 8 ) / 7 );