Специальное предложение -Нарисуйте прозрачную картинку

StackOverflow https://stackoverflow.com/questions/1375780

  •  21-09-2019
  •  | 
  •  

Вопрос

у меня есть PictureBox (называется i_MC), и я рисую на нем простое изображение (m_ImgMCN), выполняя:

Call i_MC.PaintPicture(m_ImgMCN, 0, 0, i_MC.width, i_MC.height)

теперь я хотел бы поместить прозрачное изображение на эту картинку в определенном месте.я нашел пример кода, который довольно хорошо справляется с одной проблемой:части изображения, которые не должны быть перерисованы вторым (прозрачным) изображением, перерисовываются обычным черным цветом.

алгоритм работает отлично, если фоновое изображение сверху нарисовано с помощью настройки Picture-property .не могу этого сделать, потому что это не допускает никакого растяжения.

прозрачное изображение - это простое изображение меньшего размера, чем прямоугольник, содержащий замаскированный цвет.я использовал следующий пример кода (.AutoRedraw= true для всех полей и .scaleMode = 3 'Пикселя):

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

этот код изначально находится на activevb.de , я немного модифицировал его, не меняя алгоритм или функциональность.я могу разместить ссылку на оригинальную статью.

безуспешно я пытался изменить размеры для разных промежуточных изображений, но из-за этого изображение по-прежнему получается неправильным:

часть изображения, где нарисована прозрачная картинка, является правильной, фон включен.остальная часть изображения (которая не должна быть затронута алгоритмом) перезаписывается черным цветом.

любая идея приветствуется.алгоритм для рисования 24-битных буквенных изображений тоже был бы хорош!Я довольно долго гуглил и не нашел работающего фрагмента кода.

PS:это обычный старый VB6, переходящий на .NET или любой другой язык, к сожалению, не подходит.

заранее спасибо и с наилучшими пожеланиями

Это было полезно?

Решение

черт.мой друг дал мне совет, используя TransparentBlt (MSDN) Прозрачный файл (MSDN)-Функция из WinAPI.работает сейчас довольно хорошо.спасибо тем, кто взглянул на это.

ty и gn8

что касается создания атмосферы

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top