Frage

In letzter Zeit habe ich interessiert unkomprimierte Bitmaps im Speicher darstellt. Allerdings ist eine Sache, die ich bin nicht sicher, wie man richtig implementieren ist binär Transparenz. Zum Beispiel, ich mit so etwas wie dies beginnen:

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

Ich nehme an, der einfachste Weg, dies sei:

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

Aber das scheint ein bisschen verschwenderisch (man könnte genauso gut einen Alphakanal hinzufügen). Die einzige andere Möglichkeit, die ich denken kann, ist eine der Farben zu behalten als transparent zu sein, aber dann verlieren Sie die Möglichkeit, die Farbe anzuzeigen. Gibt es eine standardisierte Möglichkeit, dies zu tun?

Wie gängige Formate (GIF, 8-bit PNG, etc.) repräsentiert das?

War es hilfreich?

Lösung

Es gibt 16 Millionen Farben, Bezeichnen eines davon als transparent wird keine große Not sein. Es sei denn, Ihr Bild 16 Megapixel ist, können Sie sicher sein, es nicht einmal alle 16 Millionen Farben nicht verwendet sowieso nur eine auswählen, die nicht verwendet wird, und es ist die Transparenz Farbe. Wenn Sie ein großes Bild zu tun haben, die sie alle, wählen Sie die man verwendet, die am wenigsten verwendet wird und es zu einer benachbarten Farbe ändern, es ungenutzt zu machen.

Wie Sie erwähnten, ein einzelnes Bit pro Pixel mit den Pixel-RGB-Daten zu speichern versucht, ist nicht effizient. Sie sollten wahrscheinlich entweder speichern alle RGB-Pixel in einen Zeiger und dann eine Bitmap der gleichen H und V Dimensionen in einem anderen Zeiger, oder Sie können chroma keying tun. Sie könnten die Daten zu speichern, mit R, G, B und Transparenz Bitmap getrennt, wie oben erwähnt, aber das ist im Allgemeinen sehr ineffizient, wenn es um es zu zeichnen kommt.

Andere Tipps

Gif verwendet eine bestimmte Farbe für transparent. (Z.B .: kann sagen 0xFFFF00 transparent ist, so dass alle Pixel mit diesem Farbdisplay als transparent sein.) Diese Farbe nicht in diesem Bild verwendet werden könnte.
PNG hat einen Alphakanal, der einen anderen int Mittel, die den Alpha-Wert des Pixels darstellt. (Z: 0 = vollkommen transparent, 255 = opaque, 128 = halb transparent)

Üblicherweise gibt es einen vierten Kanal Alpha Transparenz zu repräsentieren.

d. statt RBG, können Sie RGBA haben.

Binary Transparenz ist auch Chroma Keying genannt. Sie legen eine Farbe als transparente Farbe und in der Zeichnung Funktion ein Pixel zeichnen, wenn die Farbe nicht der Chroma-Key (bezeichnet als transparente Farbe) ist.

Per Pixel alpha verwendet, wenn Sie Multi-Level-Transparenz wie Schlagschatten tun.

Sie könnten die Transparenz in separaten Speichern speichern oder speichern, auch für jeden Kanal getrennt, z.

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

Dann width*height / 8 Bytes für den Transparenzkanal zuzuordnen, und unter der Annahme, 8 Bit pro Farbkanal können Sie die Bits wie folgt zugreifen:

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

Beachten Sie die Bits Zugriff optimiert werden kann, ist dies nur ein Beispiel.

Eine andere Lösung: Sie ein bisschen von einem der Farbkanäle streichen könnte, und definieren Sie Ihre Struktur wie folgt aus:

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

Bei der Lagerung oder den roten Kanal zu lesen, müssen Sie entsprechend skalieren, z.B. red = (uint8_t)( ( (uint16_t)pix->red * 8 ) / 7 );

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top