Wie bekomme ich Bitmap-Transparenz, ohne vorher malen zu müssen?

9

Eine neu erstellte Bitmap scheint standardmäßig einen (weißen) Hintergrund zu haben. Zumindest bestätigt eine Abfrage auf der Pixel-Eigenschaft. Aber warum wird diese Hintergrundfarbe nicht als transparente Farbe verwendet, wenn Transparent auf wahr gesetzt ist?

Betrachten Sie diesen einfachen Testcode:

%Vor%

Aus irgendeinem Grund muss die gesamte Bitmap-Oberfläche gemalt werden, bevor sie transparent erscheinen kann, was irgendwie seltsam klingt.

Die folgenden Varianten werden versucht, den Aufruf von FillRect zu eliminieren, alle mit dem gleichen Ergebnis (keine Transparenz):

  • Nur Einstellung Brush.Color ,
  • Brush.Handle := CreateSolidBrush(clWhite) ,
  • PixelFormat := pf32Bit ,
  • IgnorePalette := True ,
  • TransparantColor := clWhite ,
  • TransparantMode := tmFixed ,
  • Canvas.Pixels[0, 99] := clWhite , was nur das Pixel transparent macht,
  • Modified := True .

Der Wunsch besteht also darin, nur einen Teil einer neu erstellten Bitmap zu zeichnen und die verbleibende Fläche transparent zu machen.

Verwendung: Delphi 7, Win 7/64.

    
NGLN 11.10.2011, 20:59
quelle

3 Antworten

9

Setzen Sie einfach TransparentColor und .Brush.Color, bevor Sie die Abmessungen der Bitmap festlegen.

    
Torbins 12.10.2011, 07:06
quelle
3

Ich musste wirklich in der Lage sein, eine vollständig transparente (und ansonsten leere / leere) TBitmap einer beliebigen Größe im 32-Bit-RGBA-Format zu erstellen. Viele Male. Lazarus ist in der Lage, eine solche Bitmap in TBitmap zu laden, und nachdem sie geladen ist, können Sie sie mit Scanline und nicht mit dem RGBA-Format bearbeiten. Aber es funktioniert einfach nicht, wenn Sie TBitmap selbst erstellen. Das Pixelformat scheint vollständig ignoriert zu werden. Also, was ich gemacht habe, ist so out-of-the-box und einfach, dass es fast AMUZING (!) Ist. Aber es ist praktisch, funktioniert super nett und ist völlig unabhängig von LCL und anderen Bibliotheken von Drittanbietern. Auch hängt nicht von der Grafikeinheit ab, da sie die eigentliche 32-Bit-RGBA-BMP-Datei erzeugt (ich erzeuge sie zu TMemoryStream, die Sie anders erzeugen können). Sobald Sie es haben, können Sie es an anderer Stelle in Ihrem Code einfach mit TBitmap.LoadFrom Quelle oder TPicture.LoadFrom Quelle laden.

Die Hintergrundgeschichte Ich wollte zunächst eine korrekt formatierte BMP-Datei nach folgendem Format erstellen: Ссылка Aber es gab nur wenige Varianten des BMP-Formats, und mir war nicht klar, welchem ​​ich folgen sollte. Also entschied ich mich für einen Reverse-Engineering-Ansatz, aber die Formatbeschreibung half mir später. Ich benutzte einen grafischen Editor (ich benutzte GIMP), um eine leere 1x1 Pixel 32 RGBA BMP-Datei zu erstellen, und nannte es alpha1p.bmp, es enthielt nur nichts anderes. Dann änderte ich die Leinwand auf 10x10 Pixel und speicherte sie als alpha10p.bmp-Datei. Dann habe ich die zwei Dateien verglichen: kompilieren von zwei bmp-Dateien in vbindiff auf Ubuntu So fand ich heraus, dass die einzigen Unterschiede die hinzugefügten Pixel waren (jeder war 4 Bytes alle Nullen RGBA) und wenige andere Bytes in der Kopfzeile. Aufgrund der Format-Dokumentation der verknüpften I-Datei habe ich herausgefunden, dass es sich dabei um FileSize (in Byte), BitmapWidth (in Pixel), BitmapHeight (in Pixel) und BitmapDataSize (in Byte) handelt. Der letzte war BitmapWidth*BitmapHeight*4 , weil jedes Pixel in RGBA 4 Bytes ist. So, jetzt könnte ich nur die gesamte Sequenz von Bytes generieren, wie in alpha1p.bmp Dateien gesehen, minus 4 Bytes vom Ende (die erste der BitmapData ), dann fügen Sie 4 Bytes (alle Nullen) von RGBA-Daten für jedes Pixel der BMP, die ich erzeugen möchte, dann komme ich zurück zur ursprünglichen Sequenz und aktualisiere die variablen Teile: FileSize, Breite, Höhe und BMP-Datengröße. Und es funktioniert einwandfrei! Ich musste nur Test für BigEndian hinzufügen und würde Wort- und Doppelwort-Zahlen vor dem Schreiben austauschen. Das würde auf ARM-Plattformen, die in BigEndian arbeiten, problematisch werden.

Der Code

%Vor%

Beachten Sie, dass C_BLANK_ALPHA_BMP32_PREFIX constant im Grunde die Kopie der Bytefolge aus meiner Beispieldatei alpha1p.bmp ist, minus den letzten 4 Bytes, die das RGBA-Pixel waren. : D

Außerdem verwende ich IsBigEndian function, die so lautet:

%Vor%

Dies wird von Lazarus Wiki kopiert: Ссылка Sie können diesen Teil überspringen, wenn Sie nicht mit BigEndian-Plattformen oder Ihnen arbeiten kann eine Compiler-IFDEF-Direktive verwenden. Die Sache ist, dass, wenn Sie {$IFDEF ENDIAN_BIG} verwenden, Compiler-Dinge der Fall sind, während die Funktion tatsächlich das System testet. Dies wird im verlinkten Wiki erklärt.

Beispielnutzung

%Vor%     
Kris Jace 09.12.2017 14:23
quelle
1

Dies wird ein rotes Quadrat zeichnen und der Rest ist transparent.

%Vor%     
Shambhala 11.10.2011 22:52
quelle

Tags und Links