Windows Forms: Eine Cursor-Bitmap teilweise transparent machen

8

Ich möchte teilweise transparente Bilder in Drag / Drop-Operationen verwenden. Dies ist alles eingerichtet und funktioniert gut, aber die eigentliche Transformation zu Transparenz hat eine seltsame Nebenwirkung. Aus irgendeinem Grund scheinen die Pixel vor einem schwarzen Hintergrund zu liegen.

Das folgende Bild beschreibt das Problem:

Abbildung a) ist die Original-Bitmap.

Abbildung b) ist das, was nach dem Alpha-Blending erzeugt wurde. Offensichtlich ist das viel dunkler als der beabsichtigte 50% Alpha Filter.

Abbildung c) ist der gewünschte Effekt, Bild a) mit 50% Transparenz (wird mit einem Zeichenprogramm zur Komposition hinzugefügt).

Der Code, den ich verwende, um das transparente Bild zu erzeugen, ist folgender:

%Vor%

Weiß jemand, warum das Alpha Blending nicht funktioniert?

Update I:

Aus Gründen der Klarheit funktioniert der Code, wenn ich auf einer gezeichneten Oberfläche alphabetisch blende. Das Problem ist, dass ich ein vollständig semitransparentes Bild aus einem vorhandenen Bild erstellen und dieses als dynamischen Cursor während Drag & Drop-Operationen verwenden möchte. Selbst wenn man das obige überspringt und nur ein gefülltes Rechteck der Farbe 88ffffff malt, erhält man eine dunkelgraue Farbe. Etwas Fischiges ist mit dem Symbol los.

Update II:

Da ich eine ganze Menge recherchiert habe und glaube, dass dies etwas mit der Erstellung des Cursors zu tun hat, werde ich diesen Code auch darunter einfügen. Wenn ich GetPixel die Bitmap kurz vor dem CreateIconIndirect-Aufruf sample, scheinen die vier Farbwerte intakt zu sein. So habe ich das Gefühl, dass die Schuldigen die hbmColor- oder hbmMask-Mitglieder der IconInfo-Struktur sein könnten.

Hier ist die IconInfo-Struktur:

%Vor%

Und hier ist der Code, der den Cursor tatsächlich erzeugt:

%Vor%

Die zwei externen Funktionen sind wie folgt definiert:

%Vor%     
Pedery 06.08.2009, 00:52
quelle

5 Antworten

6

GDI + hat eine Reihe von Problemen im Zusammenhang mit Alpha-Blending beim Interop mit GDI (und Win32). In diesem Fall mischt der Aufruf von bmp.GetHbitmap () Ihr Bild mit einem schwarzen Hintergrund. Ein Artikel zu CodeProject enthält weitere Details zu dem Problem und eine Lösung, die zum Hinzufügen von Bildern zu einem Bildliste.

Sie sollten ähnlichen Code verwenden können, um HBITMAP für die Maske zu verwenden:

%Vor%     
Chris Ostler 07.08.2009, 17:30
quelle
3

Vor einiger Zeit habe ich gelesen, dass dieses Problem auf die Notwendigkeit von vormultiplizierten Alphakanälen in den Bitmaps zurückzuführen ist. Ich bin nicht sicher, ob dies ein Problem mit Windows-Cursors oder GDI war, und für mein Leben kann ich keine Dokumentation darüber finden. Während diese Erklärung korrekt ist oder auch nicht, macht der folgende Code tatsächlich das, was Sie wollen, indem Sie einen vormultiplizierten Alpha-Kanal in der Cursor-Bitmap verwenden.

%Vor%

Die pinvoke-Deklarationen finden Sie in der External-Klasse, die hier gezeigt wird:

%Vor%

Einige Anmerkungen zum Code:

  1. Um die unsichere Methode UnsafeCopy () zu verwenden, müssen Sie mit dem / unsafe-Flag kompilieren.
  2. Die Bitmap-Kopiermethoden sind hässlich, besonders die sichere Methode, die Marshal.ReadByte () / Marshal.WriteByte () Aufrufe verwendet. Es muss einen schnelleren Weg geben, Bitmap-Daten zu kopieren, während auch Alpha-Bytes eingefügt werden.
  3. Ich nehme an, dass die Quell-Bitmap in einem 24-Bit-pro-Pixel-Format gesperrt werden kann. Dies sollte jedoch kein Problem sein.
Tarsier 08.08.2009 04:12
quelle
0

Versuchen Sie, den Wert von Blue auf .7 oder .6 zu senken und sehen Sie, ob das näher an Ihren Vorstellungen liegt.

Hier ist eine gute Seite, die ColorMatrix erklärt:

    
Jim Schubert 06.08.2009 01:05
quelle
0

Wenn ich Ihren Code ausführen, um ein Bild in einer Bildbox mit einem Hintergrundrasterbild zu bearbeiten, erhalte ich den gewünschten Effekt, ohne den Code zu ändern. Vielleicht wird Ihr Bild über etwas mit einer dunklen Farbe gezeichnet ...

    
tbischel 06.08.2009 03:20
quelle
0

Verzeihen Sie, wenn mein Vorschlag zu simpel ist (ich bin noch neu in C #), aber ich habe das auf der MSDN-Site gefunden und vielleicht Dies könnte Sie in die richtige Richtung weisen?

/ matt

    
Matt Dewey 06.08.2009 14:46
quelle