Transparente Bitmaps mittels GDI

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Transparente Bitmaps mittels GDI

Beitrag von Fluid Byte »

Der folgende Code demonstriert wie man Bitmaps mit transparenten Bereichen in einer gewöhnlichen, auf Fenster-basierenden Anwendung darstellen kann. Die Methode bedient sich einer bereits existierenden schwarz/weiss Maske welche mit dem gewünschtem Bild kombiniert wird. Dies ist mit Abstand die Prozessorschonendste Technik die Ich kenne. Außerdem rückwärts-kompatibel bis Win95.

Code: Alles auswählen

Procedure WindowCallback(hWnd.l,uMsg.l,wParam.l,lParam.l) 
    Select uMsg
        Case #WM_PAINT
		hdc = BeginPaint_(hwnd,ps.PAINTSTRUCT)
		                        
		hdcMem = CreateCompatibleDC_(hdc)
		
		SelectObject_(hdcMem,ImageID(1))
		BitBlt_(hdc,60,20,200,200,hdcMem,0,0,#SRCAND)
			
		SelectObject_(hdcMem,ImageID(0))    
		BitBlt_(hdc,60,20,200,200,hdcMem,0,0,#SRCPAINT)
		
		DeleteDC_(hdcMem)        
		
		EndPaint_(hwnd,ps)  
    EndSelect

    ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

CreateImage(0,200,200)
CreateImage(1,200,200)

StartDrawing(ImageOutput(0))
For i=0 To 100
	FrontColor(RGB(50+i*205/100,0,0))
	Ellipse(100,100,100-i,100-i)
Next
StopDrawing()

StartDrawing(ImageOutput(1))
Box(0,0,200,200,#White)
Ellipse(100,100,100,100,0)
StopDrawing()

OpenWindow(0,0,0,320,240,"Bitmap Mask",#WS_OVERLAPPEDWINDOW | 1)

SetWindowCallback(@WindowCallback())

SetWindowColor(0,RGB(80,130,180))

While WaitWindowEvent() ! 16 : Wend
Windows 10 Pro, 64-Bit / Outtakes | Derek
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

supi! :allright:
danke, dass du meiner bitte nachgekommen bist. :D
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Imma' doch! Bild

Ach ja noch was...

Wer unbedingt eine andere transparente Farbe als Schwarz benötigt:

1.) Im Quellbild ein "fake black" benutzen. Soll heißen man macht aus RGB(0,0,0) einfach RGB(1,1,1).

2.) Bei einem einfarbigen Hintergrund einfach Schwarz nehmen. Bild

3.) Ein zusätzliches, schwarzes Bild was unter Quellbild und Maske gepackt wird und als Deckfarbe fungiert. Änlich wie bei CMYK im Druck.
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Ganz schicker Code, aber was ich viel interessanter finde ist "While WaitWindowEvent() ! 16 : Wend". Bin bis jetzt nämlich nie auf die Idee gekommen "<>" mit "!" zu ersetzen, auch wenn man das "selbe" erhält.
Thx für den Tip ;)
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Benutzeravatar
Ja!
Beiträge: 271
Registriert: 02.01.2006 16:13
Wohnort: Stuttgart

Beitrag von Ja! »

Deeem2031 hat geschrieben:Ganz schicker Code, aber was ich viel interessanter finde ist "While WaitWindowEvent() ! 16 : Wend". Bin bis jetzt nämlich nie auf die Idee gekommen "<>" mit "!" zu ersetzen, auch wenn man das "selbe" erhält.
Thx für den Tip ;)

Hmm, jetzt wo Du's sagst, tatsächlich ist auch mir das noch nie
eingefallen.. Dabei ist es so naheliegend! :-)

..und das nach so vielen Jahren.. :-D
PureBasic 3.94 ; 4.2 ; 4.3
sechsrad
Rüpel
Beiträge: 112
Registriert: 01.02.2008 13:31

Beitrag von sechsrad »

Code: Alles auswählen

Procedure WindowCallback(hWnd.l,uMsg.l,wParam.l,lParam.l)
    Select uMsg
      Case #WM_PAINT
      hdc = BeginPaint_(hwnd,ps.PAINTSTRUCT)
                             
      hdcMem = CreateCompatibleDC_(hdc)
      
      SelectObject_(hdcMem,ImageID(1))
      BitBlt_(hdc,60,20,200,200,hdcMem,0,0,#SRCAND)
         
      SelectObject_(hdcMem,ImageID(0))   
      BitBlt_(hdc,60,20,200,200,hdcMem,0,0,#SRCPAINT)
      
      DeleteDC_(hdcMem)       
      
      EndPaint_(hwnd,ps) 
    EndSelect

    ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure


OpenWindow(0,0,0,400,400,"sprites!",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)

CreateImage(0,200,200)
CreateImage(1,200,200)

StartDrawing(ImageOutput(0))
For i=0 To 100
   FrontColor(RGB(50+i*205/100,0,0))
   Ellipse(100,100,100-i,100-i)
Next
StopDrawing()

StartDrawing(ImageOutput(1))
Box(0,0,200,200,#White)
Ellipse(100,100,100,100,0)
StopDrawing()


SetWindowCallback(@WindowCallback())

;SetWindowColor(0,RGB(80,130,180))

While WaitWindowEvent() ! 16 : Wend
OpenWindowedScreen(WindowID(0),5,5,50,50,0,0,0)

..wenn ich das noch zusätzlich reinsetze geht das Programm ins Grab.

warum?
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

sechsrad hat geschrieben:warum?
Du erwartest jetzt wirklich eine Antwort vom arbeitsscheuen Fluid Byte -
Gesint, dem ein Wurm im Arsch steckt
? :roll:

Sachen gibt's...
a²+b²=mc²
Antworten