[GDI] Eine Pixelfarbe (zB 0xFFFFFF) nicht mit zeichen/ transparent machen

  • Hey
    Ich lade ein Image mit GDIImageLoadFromFile. Jetzt möchte ich eine Farbe auswählen können, die ich nicht mitzeichne. Wenn ich dies aber mit BitmapGetPixel und DCSetPixel oder BitmapSetPixel mache, dauert dies viel zu lange.
    Gibt es keine andere und schnellere Möglichkeit?
    Wäre nett von euch, wenn ihr mir weiterhelfen könntet.
    Vielen Dank, AntiSpeed

    Nur keine Hektik - das Leben ist stressig genug

  • Dazu brauchst du ein paar Funktionen aus der GDIP.au3 (findest du im englischen Forum). Hier mal ein Beispiel.

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <GDIPlus.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $iARGB_From = 0xFFD0D0D0
    $iARGB_To = 0xFFFFFFFF

    [/autoit] [autoit][/autoit] [autoit]

    $iARGB_BG = 0xFF505050

    [/autoit] [autoit][/autoit] [autoit]

    $sFilePath = FileOpenDialog("Bild auswählen", "", "Bilder (*.jpg;*.png;*.bmp)")
    If @error Then Exit

    [/autoit] [autoit][/autoit] [autoit]

    $hWnd = GUICreate("ColorKey", 400, 400)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
    _GDIPlus_GraphicsClear($hGraphics, $iARGB_BG)

    [/autoit] [autoit][/autoit] [autoit]

    $hImage = _GDIPlus_ImageLoadFromFile($sFilePath)
    $iWidth = _GDIPlus_ImageGetWidth($hImage)
    $iHeight = _GDIPlus_ImageGetHeight($hImage)

    [/autoit] [autoit][/autoit] [autoit]

    $hIA = _GDIPlus_ImageAttributesCreate()

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_ImageAttributesSetColorKeys($hIA, 0, True, $iARGB_From, $iARGB_To)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImageRectRectIA($hGraphics, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, 400, 400, $hIA)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()

    [/autoit] [autoit][/autoit] [autoit]

    While GUIGetMsg() <> -3
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;GDIP.au3 Functions

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_ImageAttributesCreate
    ; Description ...: Creates an ImageAttributes object
    ; Syntax.........: _GDIPlus_ImageAttributesCreate()
    ; Parameters ....: None
    ; Return values .: Success - Pointer to a new ImageAttribute object
    ; Failure - 0 and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: After you are done with the object, call _GDIPlus_ImageAttributesDispose to release the object resources
    ; Related .......: _GDIPlus_ImageAttributesDispose
    ; Link ..........; @@MsdnLink@@ GdipCreateImageAttributes
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_ImageAttributesCreate()
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateImageAttributes", "int*", 0)

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then Return SetError(@error, @extended, 0)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[1]
    EndFunc ;==>_GDIPlus_ImageAttributesCreate

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_ImageAttributesSetColorKeys
    ; Description ...: Sets or clears the color key (transparency range) for a specified category
    ; Syntax.........: _GDIPlus_ImageAttributesSetColorKeys($hImageAttributes[, $iColorAdjustType = 0[, $fEnable = False[, $iARGBLow = 0[, $iARGBHigh = 0]]]])
    ; Parameters ....: $hImageAttributes - Pointer to an ImageAttribute object
    ; $iColorAdjustType - The category for which the color key is set or cleared:
    ; |0 - Color adjustment applies to all categories that do not have adjustment settings of their own
    ; |1 - Color adjustment applies to bitmapped images
    ; |2 - Color adjustment applies to brush operations in metafiles
    ; |3 - Color adjustment applies to pen operations in metafiles
    ; |4 - Color adjustment applies to text drawn in metafiles
    ; $fEnable - If True, transparency range for the specified category is applied; otherwise, transparency
    ; +range for the specified category is cleared, in which case $iARGBLow and $iARGBHigh are ignored
    ; $iARGBLow - Alpha, Red, Green and Blue components of a color that specifies the low color-key value
    ; $iARGBHigh - Alpha, Red, Green and Blue components of a color that specifies the high color-key value
    ; Return values .: Success - True
    ; Failure - False and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: Any color that has each of its three components (red, green, blue) between the corresponding components of the
    ; +high and low color keys is made transparent
    ; Related .......: None
    ; Link ..........; @@MsdnLink@@ GdipSetImageAttributesColorKeys
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_ImageAttributesSetColorKeys($hImageAttributes, $iColorAdjustType = 0, $fEnable = False, $iARGBLow = 0, $iARGBHigh = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetImageAttributesColorKeys", "hwnd", $hImageAttributes, "int", $iColorAdjustType, "int", $fEnable, "uint", $iARGBLow, "uint", $iARGBHigh)

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
    EndFunc ;==>_GDIPlus_ImageAttributesSetColorKeys

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_GraphicsDrawImageRectRectIA
    ; Description ...: Draws an image
    ; Syntax.........: _GDIPlus_GraphicsDrawImageRectRectIA($hGraphics, $hImage, $nSrcX, $nSrcY, $nSrcWidth, $nSrcHeight, $nDstX, $nDstY, $nDstWidth, $nDstHeight[, $hImageAttributes = 0[, $iUnit = 2]])
    ; Parameters ....: $hGraphics - Pointer to a Graphics object
    ; $hImage - Pointer to an Image object
    ; $iSrcX - The X coordinate of the upper left corner of the source image
    ; $iSrcY - The Y coordinate of the upper left corner of the source image
    ; $iSrcWidth - Width of the source image
    ; $iSrcHeight - Height of the source image
    ; $iDstX - The X coordinate of the upper left corner of the destination image
    ; $iDstY - The Y coordinate of the upper left corner of the destination image
    ; $iDstWidth - Width of the destination image
    ; $iDstHeight - Height of the destination image
    ; $hImageAttributes - Pointer to an ImageAttributes object that specifies the color and size attributes of the image to be drawn
    ; $iUnit - Unit of measurement:
    ; |0 - World coordinates, a nonphysical unit
    ; |1 - Display units
    ; |2 - A unit is 1 pixel
    ; |3 - A unit is 1 point or 1/72 inch
    ; |4 - A unit is 1 inch
    ; |5 - A unit is 1/300 inch
    ; |6 - A unit is 1 millimeter
    ; Return values .: Success - True
    ; Failure - False and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: None
    ; Related .......: None
    ; Link ..........; @@MsdnLink@@ GdipDrawImageRectRect
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_GraphicsDrawImageRectRectIA($hGraphics, $hImage, $nSrcX, $nSrcY, $nSrcWidth, $nSrcHeight, $nDstX, $nDstY, $nDstWidth, $nDstHeight, $hImageAttributes = 0, $iUnit = 2)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectRect", "hwnd", $hGraphics, "hwnd", $hImage, "float", $nDstX, "float", _
    $nDstY, "float", $nDstWidth, "float", $nDstHeight, "float", $nSrcX, "float", $nSrcY, "float", $nSrcWidth, "float", _
    $nSrcHeight, "int", $iUnit, "hwnd", $hImageAttributes, "int", 0, "int", 0)

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
    EndFunc ;==>_GDIPlus_GraphicsDrawImageRectRectIA

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GDIPlus_ImageAttributesDispose
    ; Description ...: Releases an ImageAttributes object
    ; Syntax.........: _GDIPlus_ImageAttributesDispose($hImageAttributes)
    ; Parameters ....: $hImageAttributes - Pointer to an ImageAttribute object
    ; Return values .: Success - True
    ; Failure - False and either:
    ; |@error and @extended are set if DllCall failed
    ; |$GDIP_STATUS contains a non zero value specifying the error code
    ; Remarks .......: None
    ; Related .......: _GDIPlus_ImageAttributesCreate
    ; Link ..........; @@MsdnLink@@ GdipDisposeImageAttributes
    ; Example .......; No
    ; ===============================================================================================================================
    Func _GDIPlus_ImageAttributesDispose($hImageAttributes)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipDisposeImageAttributes", "hwnd", $hImageAttributes)

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then Return SetError(@error, @extended, False)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[0] = 0
    EndFunc ;==>_GDIPlus_ImageAttributesDispose

    [/autoit]
  • Hi,
    ich hab hier noch eine schnelle Assembler Lösung. (Quick & Dirty ^^)

    Farbe Transparent machen
    [autoit]

    #AutoIt3Wrapper_UseX64=n
    #include <GDIPlus.au3>
    #include <include/AssembleIt.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ;~ $sFile = FileOpenDialog("", @ScriptDir, "Bild Dateien (*.*)")
    If @error Then Exit
    $sFile = @ScriptDir & "\TestBild.bmp"

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    $hBitmap = _GDIPlus_BitmapCreateFromFile($sFile) ;Hier bitte pfad anpassen <<<<<<<<<<<<<
    $iWidth = _GDIPlus_ImageGetWidth($hBitmap)
    $iHeight = _GDIPlus_ImageGetHeight($hBitmap)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ColorIgno($hBitmap,$iWidth,$iHeight,0xFFFF0000)

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate("", $iWidth, $iHeight)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    $hGr = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While GUIGetMsg() <> -3
    _GDIPlus_GraphicsDrawImage($hGr, $hBitmap, 0, 0)
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func ColorIgno($hBitmap, $iWidth, $iHeight, $iSearchColor, $iReplaceColor = 0x00000000)
    Local Static $tCodeBuffer = DllStructCreate("byte[30]") ;reserve Memory for opcodes
    DllStructSetData($tCodeBuffer, 1, "0x8B7424048B4C24088B5C240C8B542410391E740683C604E2F7C38916EBF6") ;write opcodes into memory

    [/autoit] [autoit][/autoit] [autoit]

    $tBitmap = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)
    If @error Then Return SetError(1, @error, -1)
    $pBitmap = DllStructGetData($tBitmap, "Scan0")

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "ptr", $pBitmap, "int", $iWidth * $iHeight, "int", $iSearchColor, "int", $iReplaceColor)
    _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmap)
    If @error Then Return SetError(2, @error, -1)
    Return True
    EndFunc ;==>ColorIgno

    [/autoit] [autoit][/autoit] [autoit]

    #cs
    Func _ColorIgno()
    _("use32")
    _("mov esi,dword[esp+4]")
    _("mov ecx,dword[esp+8]")
    _("mov ebx,dword[esp+12]")
    _("mov edx,dword[esp+16]")

    [/autoit] [autoit][/autoit] [autoit]

    _("_mainloop:")

    [/autoit] [autoit][/autoit] [autoit]

    _("cmp dword[esi],ebx")
    _("je ignopx")

    [/autoit] [autoit][/autoit] [autoit]

    _("weiter:")

    [/autoit] [autoit][/autoit] [autoit]

    _("add esi,4")
    _("loop _mainloop")

    [/autoit] [autoit][/autoit] [autoit]

    _("ret")

    [/autoit] [autoit][/autoit] [autoit]

    _("ignopx:")
    _("mov dword[esi],edx")
    _("jmp weiter")
    EndFunc ;==>_ColorIgno
    _AssembleIt("int", "_ColorIgno", "ptr", $pBitmap, "int", $iWidth * $iHeight, 0xFF000000, 0x00000000)
    #ce

    [/autoit]


    Farbkanal Ignorieren
    [autoit]

    #AutoIt3Wrapper_UseX64=n
    #include <GDIPlus.au3>
    ;~ #include <include/AssembleIt.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $sFile = FileOpenDialog("", @ScriptDir, "Bild Dateien (*.*)")
    If @error Then Exit

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    $hBitmap = _GDIPlus_BitmapCreateFromFile($sFile) ;Hier bitte pfad anpassen <<<<<<<<<<<<<
    $iWidth = _GDIPlus_ImageGetWidth($hBitmap)
    $iHeight = _GDIPlus_ImageGetHeight($hBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    ;Locken und Pointer hohlen
    $tBitmap = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)
    $pBitmap = DllStructGetData($tBitmap, "Scan0")

    [/autoit] [autoit][/autoit] [autoit]

    ;0xFF00FFFF = Rot wird gekillt
    ;0xFFFF00FF = Grün wird gekillt
    ;0xFFFFFF00 = Blau wird gekillt
    ;Wo FF steht bleibt der Farbkanal bestehen 00 löscht ihn (setzt ihn auf 0)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $tCodeBuffer = DllStructCreate("byte[20]") ;reserve Memory for opcodes
    DllStructSetData($tCodeBuffer, 1, "0x8B7424048B4C24088B5C240C211E83C604E2F9C3") ;write opcodes into memory
    $ret = DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "ptr", $pBitmap, "int", $iWidth * $iHeight, "int", 0xFF00FFFF, "int", 0)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmap)
    $hGUI = GUICreate("", $iWidth, $iHeight)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    $hGr = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While GUIGetMsg() <> -3
    _GDIPlus_GraphicsDrawImage($hGr, $hBitmap, 0, 0)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    #cs
    Func _ColorIgno()
    _("use32")
    _("mov esi,dword[esp+4]")
    _("mov ecx,dword[esp+8]")
    _("mov ebx,dword[esp+12]")

    [/autoit] [autoit][/autoit] [autoit]

    _("_mainloop:")
    _("and dword[esi],ebx")
    _("add esi,4")
    _("loop _mainloop")
    _("ret")
    EndFunc ;==>_ColorIgno
    #ce

    [/autoit]
  • Dafür bietet sich die Funktion TransparentBlt() an!
    Damit kannst du eine Farbe wählen, die beim Blitten transparent gezeichnet wird. Alternativ funktioniert das auch mit "normalem" blitten und der Verwendung einer Maske.
    Im Script ist auch die Verwendung der Bitmaps als Button vorgestellt

    Spoiler anzeigen
    [autoit]

    #Include <WinAPIEx.au3>
    #Include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('MustDeclareVars', 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $STM_SETIMAGE = 0x0172
    Global Const $STM_GETIMAGE = 0x0173

    [/autoit] [autoit][/autoit] [autoit]

    Global $hForm, $Pic1, $Pic2, $hPic1, $hPic2, $hObj, $hBmp, $hBitmap1, $hBitmap2, $hDC, $hDestDC, $hDestSv, $hSrcDC, $hSrcSv

    [/autoit] [autoit][/autoit] [autoit]

    ; Create GUI
    $hForm = GUICreate('MyGUI', 260, 140)
    GUICtrlCreatePic(@WindowsDir&"\angler.bmp",0,0,260,140)
    $Pic1 = GUICtrlCreatePic('', 20, 20, 100, 100)
    $hPic1 = GUICtrlGetHandle($Pic1)
    $Pic2 = GUICtrlCreatePic('', 140, 20, 100, 100)
    $hPic2 = GUICtrlGetHandle($Pic2)

    [/autoit] [autoit][/autoit] [autoit]

    ; Create bitmap1
    $hDC = _WinAPI_GetDC($hPic1)
    $hDestDC = _WinAPI_CreateCompatibleDC($hDC)
    $hBitmap1 = _WinAPI_CreateCompatibleBitmapEx($hDC, 100, 100, 0xFF00FF)
    $hDestSv = _WinAPI_SelectObject($hDestDC, $hBitmap1)
    $hBmp = _WinAPI_CreateCompatibleBitmapEx($hDC, 70, 70, 0x00A060)
    _WinAPI_DrawBitmap($hDestDC, 15, 15, $hBmp)
    ;_WinAPI_FreeObject($hBmp)
    $hBmp = _WinAPI_CreateCompatibleBitmapEx($hDC, 40, 40, 0xFF00FF)
    _WinAPI_DrawBitmap($hDestDC, 30, 30, $hBmp)
    ;_WinAPI_FreeObject($hBmp)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_ReleaseDC($hPic1, $hDC)
    _WinAPI_SelectObject($hDestDC, $hDestSv)
    _WinAPI_DeleteDC($hDestDC)

    [/autoit] [autoit][/autoit] [autoit]

    ; Create bitmap2
    $hDC = _WinAPI_GetDC($hPic2)
    $hDestDC = _WinAPI_CreateCompatibleDC($hDC)
    $hBitmap2 = _WinAPI_CreateCompatibleBitmapEx($hDC, 100, 100, _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_3DFACE)))
    $hDestSv = _WinAPI_SelectObject($hDestDC, $hBitmap2)
    $hSrcDC = _WinAPI_CreateCompatibleDC($hDC)
    $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hBitmap1)
    _WinAPI_TransparentBlt($hDestDC, 0, 0, 100, 100, $hSrcDC, 0, 0, 100, 100, 0xFF00FF)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_ReleaseDC($hPic1, $hDC)
    _WinAPI_SelectObject($hDestDC, $hDestSv)
    _WinAPI_SelectObject($hSrcDC, $hSrcSv)
    _WinAPI_DeleteDC($hDestDC)
    _WinAPI_DeleteDC($hSrcDC)

    [/autoit] [autoit][/autoit] [autoit]

    ; Set bitmaps to controls
    For $i = 1 To 2
    _SendMessage(Eval('hPic' & $i), $STM_SETIMAGE, 0, Eval('hBitmap' & $i))
    $hObj = _SendMessage(Eval('hPic' & $i), $STM_GETIMAGE)
    If $hObj <> Eval('hBitmap' & $i) Then
    ;_WinAPI_FreeObject(Eval('hBitmap' & $i))
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = -3

    [/autoit]