Spezial-Draw transparentes Bild
-
21-09-2019 - |
Frage
hat einen PictureBox (genannt i_MC) und ich ein einfaches Bild zeichnen (m_ImgMCN) auf, es zu tun:
Call i_MC.PaintPicture(m_ImgMCN, 0, 0, i_MC.width, i_MC.height)
Jetzt würde Ich mag ein transparentes Bild auf diesem Bild setzen, auf eine bestimmte Position. Ich fand einen Beispielcode, der den Job ganz gut mit einem Problem macht: Teile des Bildes, die mit dem zweiten (transparent) Bild ist overdrawn mit schlichtem Schwarz nicht overdrawn sollten
.die algo funktioniert perfekt, wenn das Hintergrundbild von oben durch Einstellen der Picture-Eigenschaft gezogen wird. kann dies nicht tun, weil diese jede Dehnung nicht zulässt.
das transparente Bild ist ein einfaches Bild kleiner als der Kasten eine Farbe enthält, die maskiert ist. Ich habe den folgenden Beispielcode (.AutoRedraw = true für alle Boxen und .ScaleMode = 3 ‚Pixel) verwendet:
Option Explicit
Private Declare Function BitBlt Lib "gdi32" (ByVal hDCDest As _
Long, ByVal XDest As Long, ByVal YDest As Long, ByVal _
nWidth As Long, ByVal nHeight As Long, ByVal hDCSrc _
As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal _
dwRop As Long) As Long
Private Declare Function CreateBitmap Lib "gdi32" (ByVal nWidth _
As Long, ByVal nHeight As Long, ByVal nPlanes As Long, _
ByVal nBitCount As Long, lpBits As Any) As Long
Private Declare Function SetBkColor Lib "gdi32" (ByVal hdc As _
Long, ByVal crColor As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As _
Long, ByVal hObject As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal _
hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) _
As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc _
As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) _
As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject _
As Long) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Dim R As RECT
Private Sub TranspPic(OutDstDC&, DstDC&, SrcDC&, SrcRect _
As RECT, ByVal DstX&, ByVal DstY&, _
TransColor&)
Dim Result&, W&, H&
Dim MonoMaskDC&, hMonoMask&, MonoInvDC&, hMonoInv&
Dim ResultDstDC&, hResultDst&, ResultSrcDC&, hResultSrc&
Dim hPrevMask&, hPrevInv&, hPrevSrc&, hPrevDst&
W = SrcRect.Right - SrcRect.Left
H = SrcRect.Bottom - SrcRect.Top
'Generieren einer Monochromen & einer inversen Maske
MonoMaskDC = CreateCompatibleDC(DstDC)
MonoInvDC = CreateCompatibleDC(DstDC)
hMonoMask = CreateBitmap(W, H, 1, 1, ByVal 0&)
hMonoInv = CreateBitmap(W, H, 1, 1, ByVal 0&)
hPrevMask = SelectObject(MonoMaskDC, hMonoMask)
hPrevInv = SelectObject(MonoInvDC, hMonoInv)
'Puffer erstellen
ResultDstDC = CreateCompatibleDC(DstDC)
ResultSrcDC = CreateCompatibleDC(DstDC)
hResultDst = CreateCompatibleBitmap(DstDC, W, H)
hResultSrc = CreateCompatibleBitmap(DstDC, W, H)
hPrevDst = SelectObject(ResultDstDC, hResultDst)
hPrevSrc = SelectObject(ResultSrcDC, hResultSrc)
'Sourcebild in die monochrome Maske kopieren
Dim OldBC As Long
OldBC = SetBkColor(SrcDC, TransColor)
Result = BitBlt(MonoMaskDC, 0, 0, W, H, SrcDC, _
SrcRect.Left, SrcRect.Top, vbSrcCopy)
TransColor = SetBkColor(SrcDC, OldBC)
'Inverse Maske erstellen
Result = BitBlt(MonoInvDC, 0, 0, W, H, _
MonoMaskDC, 0, 0, vbNotSrcCopy)
'Hintergrund des Zielbildes auslesen
Result = BitBlt(ResultDstDC, 0, 0, W, H, _
DstDC, DstX, DstY, vbSrcCopy)
'AND mit der Maske
Result = BitBlt(ResultDstDC, 0, 0, W, H, _
MonoMaskDC, 0, 0, vbSrcAnd)
'Überlappung des Sourcebildes mit dem Zielbild auslesen
Result = BitBlt(ResultSrcDC, 0, 0, W, H, SrcDC, _
SrcRect.Left, SrcRect.Top, vbSrcCopy)
'AND mit der invertierten, monochromen Maske
Result = BitBlt(ResultSrcDC, 0, 0, W, H, _
MonoInvDC, 0, 0, vbSrcAnd)
'XOR mit beiden
Result = BitBlt(ResultDstDC, 0, 0, W, H, _
ResultSrcDC, 0, 0, vbSrcInvert)
'Ergebnis in das Zielbild kopieren
Result = BitBlt(OutDstDC, DstX, DstY, W, H, _
ResultDstDC, 0, 0, vbSrcCopy)
'Erstellte Objekte & DCs wieder freigeben
hMonoMask = SelectObject(MonoMaskDC, hPrevMask)
DeleteObject hMonoMask
DeleteDC MonoMaskDC
hMonoInv = SelectObject(MonoInvDC, hPrevInv)
DeleteObject hMonoInv
DeleteDC MonoInvDC
hResultDst = SelectObject(ResultDstDC, hPrevDst)
DeleteObject hResultDst
DeleteDC ResultDstDC
hResultSrc = SelectObject(ResultSrcDC, hPrevSrc)
DeleteObject hResultSrc
DeleteDC ResultSrcDC
End Sub
Private Sub MovePicTo(ByVal X&, ByVal Y&)
i_MC.Cls
picSrc.Picture = m_ImgMCN
With R
.Left = 0
.Top = 0
.Right = Picture2.ScaleWidth
.Bottom = Picture2.ScaleHeight
End With
Call TranspPic(i_MC.hdc, i_MC.hdc, picSrc.hdc, R, X, Y, vbWhite)
i_MC.Refresh
DoEvents
End Sub
Dieser Code befindet sich ursprünglich auf activevb.de, ich es verändert ein wenig, ohne den Algorithmus oder die Funktionalität zu ändern. i kann einen Link zu einem Original-Artikel veröffentlichen.
ohne Erfolg, ich habe versucht, die Größen für die verschiedenen Zwischenbilder zu ändern, aber es hält die Malerei das Bild falsch:
der Teil des Bildes, wo das transparente Bild gezeichnet wird, korrekt ist, wird der Hintergrund enthält. der Rest des Bildes (die von der Algo nicht berührt werden soll) mit schwarz überschreibt.
jede Idee ist willkommen. ein Algorithmus 24-Bit alphablended Bilder zu malen wäre schön, wie gut! Ich habe ziemlich lange gegoogelt und habe kein Arbeits Stück Code finden.
PS: Das ist das gute alte VB6, bewegt zu .NET oder einer anderen Sprache ist leider keine Option
.Vielen Dank im Voraus und mit freundlichen Grüßen
Lösung
verdammt. ein Freund von mir gab mir den Tipp mit dem TransparentBlt (MSDN ) -Function von WinAPI. funktioniert jetzt ganz gut. diejenigen, die durch einen Blick an ihm nahm.
ty & gn8
Bezug atmocreations