Question

Dernièrement, je me suis intéressé à la représentation de bitmaps non compressés en mémoire. Cependant, je ne suis pas sûr de savoir comment mettre en œuvre correctement la transparence binaire. Par exemple, je commence avec quelque chose comme ceci:

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

Je suppose que le moyen le plus simple serait le suivant:

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

Mais cela semble un peu inutile (vous pourriez aussi bien ajouter un canal alpha complet). La seule autre possibilité à laquelle je peux penser est de réserver l’une des couleurs comme étant transparente, mais vous perdrez alors la possibilité d’afficher cette couleur. Existe-t-il un moyen standard de le faire?

Comment les formats courants (GIF, PNG 8 bits, etc.) représentent-ils cela?

Était-ce utile?

La solution

Il y a 16 millions de couleurs, en désignant l’une comme transparente ne sera pas un gros problème. Sauf si votre image mesure 16 mégapixels, vous pouvez être sûr qu'elle n'utilise même pas les 16 millions de couleurs, choisissez-en une qui ne soit pas utilisée et faites-en la couleur de transparence. Si vous avez une grande image qui les utilise toutes, sélectionnez celle qui est le moins utilisée et remplacez-la par une couleur adjacente, en la rendant inutilisée.

Comme vous l'avez indiqué, essayer de stocker un seul bit par pixel avec les données RVB de pixels n'est pas efficace. Vous devriez probablement soit stocker tous les pixels RVB dans un pointeur, puis une image bitmap des mêmes dimensions H et V dans un autre pointeur, ou bien vous pouvez utiliser l'incrustation en chrominance. Vous pouvez stocker les données avec R, G, B et le bitmap de transparence séparément, comme indiqué ci-dessus, mais cela est généralement très inefficace pour le dessiner.

Autres conseils

Gif utilise une couleur spécifiée pour le transparent. (Par exemple, supposons que 0xFFFF00 soit transparent, tous les pixels de cette couleur seront affichés en tant que transparents.) Cette couleur ne peut pas être utilisée dans cette image.
Png a un canal alpha, ce qui signifie un autre int qui représente la valeur alpha du pixel. (par exemple: 0 = totalement transparent, 255 = opaque, 128 = semi-transparent)

Généralement, il existe un quatrième canal Alpha pour représenter la transparence.

i.e. au lieu de RBG, vous pouvez avoir RGBA.

La transparence binaire est aussi appelée clé chroma. Vous désignez une couleur en tant que couleur transparente et, dans votre fonction de dessin, dessinez un pixel si sa couleur n'est pas la clé de chrominance (appelée couleur transparente).

Par pixel, l'alpha est utilisé lorsque vous utilisez une transparence à plusieurs niveaux telle que des ombres portées.

Vous pouvez stocker le transparent dans une mémoire distincte ou même stocker chaque canal séparément, par exemple:

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

Allouez ensuite width * height / 8 octets pour le canal de transparence. En supposant 8 bits par canal de couleur, vous pouvez accéder aux bits suivants:

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

Remarque, l'accès aux bits peut être optimisé. Il ne s'agit que d'un exemple.

Autre solution: vous pouvez glisser un des canaux de couleur et définir votre structure comme suit:

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

Lors du stockage ou de la lecture du canal rouge, vous devez redimensionner en conséquence, p. ex. red = (uint8_t) (((uint16_t) pix- > red * 8) / 7);

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top