Transparenz bei Bildern

  • Hallo,
    ich bin schon seit längerem an einem Projekt dabei wo ich eine Form habe die fast nur aus Bildern besteht.
    Nun benötige ich dort ein Ladebalken. Problem bei dieser Geschichte ist, das mein Ladebalkenbild abgerundete Kannten besitzt und somit als weiß angezeigt wird.
    Gibt es eine Möglichkeit bei meiner Funktion irgend wie Transparents mit ein zu bauen?

    Spoiler anzeigen
    [autoit]

    Func _GuiCreatePic($iHwnd, $iPic, $iX, $iY, $iW, $iH)
    $bImage_Pic = _GDIPlus_ImageLoadFromFile($iPic)

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

    $bWidth = _GDIPlus_ImageGetWidth($bImage_Pic)
    $bHeight = _GDIPlus_ImageGetHeight($bImage_Pic)

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

    $hbmpPic = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bImage_Pic)

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

    $iGui = GUICreate("", $iW - 1, $iH - 1, $iX, $iY, BitOR($WS_POPUP, $WS_CHILD, $WS_VISIBLE), $WS_EX_MDICHILD, $iHwnd)
    $iPic = GUICtrlCreatePic("", -1, -1, $bWidth + 1, $bHeight + 1, BitOR($SS_NOTIFY, $WS_CLIPSIBLINGS, $GUI_SS_DEFAULT_PIC))
    GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hbmpPic)

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

    Return $iGui
    EndFunc ;==>_GuiCreatePic

    [/autoit]

    Ich habe es bereits mit der Funktion SetTransparentBitmap ausprobiert, aber da bekomme ich das Bild garnicht erst angezeigt.
    So nebenbei, mein Bild ist eine PNG.
    Vielen Dank für eure Hilfe :)

    mfg Freaky :)

  • PNGs werden nicht vom Pic Control unterstützt und die von ihm unterstützten Bitmaps (die Funktion wandelt nur PNG zu BMP) können auch keinen Alphachannel haben soweit ich weiß. Es gibt nur die Möglichkeit eine GIF zu benutzen, aber die unterstützt nur volle oder gar keine Transparenz, keine zwischenwerte. Du könntest entweder das Bild direkt mit GDI+ auf die GUI zeichnen, oder den Hintergrund deines Ladebalkenbildes in der Hintergrundfarbe der GUI färben.

  • Hey,
    das Bild wird schon geladen und angezeigt bei meiner Funktion und das Pic Control ist einfach nur da um das Bild drüber zu legen.
    Und das mit die transparente Stelle mit dem Hintergrund der Gui füllen habe ich mir auch schon gedacht. Problem ist aber, dass mein Hintergrund so ein Rauscheffekt hat und sich die ganze Zeit ändern würde.
    mfg Freaky

  • Ich sehe gerade, dass GUICTrlCreatePic wohl doch Teiltransparenz unterstützt (also Bitmaps mit Alphachannel). Und jetzt weiß ich auch wo dein Problem liegt..
    Dieser weiße Rand ist der Hintergrund der GUI die du in deiner GUICreatePic Funktion erstellst. Das Bild mag transparent sein, aber die GUI ist es nicht. Du müsstest also den Hintergrund der GUI von deinem Pic Control ändern, oder das Bild in ein Pic Control in deiner HauptGUI packen. Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <Constants.au3>
    #include <WindowsConstants.au3>
    #include <StaticConstants.au3>
    #include <GDIPlus.au3>

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

    Global Const $STM_SETIMAGE = 0x0172

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

    _GDIPlus_Startup()

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

    $bImage_Pic = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Test.png")
    $bWidth = _GDIPlus_ImageGetWidth($bImage_Pic)
    $bHeight = _GDIPlus_ImageGetHeight($bImage_Pic)
    $hbmpPic = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bImage_Pic)

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

    $hwnd = GUICreate("ddd")
    $iPic = GUICtrlCreatePic("", 50, 50, $bWidth, $bHeight, BitOR($SS_NOTIFY, $WS_CLIPSIBLINGS, $GUI_SS_DEFAULT_PIC))
    GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hbmpPic)
    GUISetState()

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

    While GUIGetMsg() <> -3
    WEnd

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

    _GDIPlus_ImageDispose($bImage_Pic)
    _GDIPlus_Shutdown()

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

    _WinAPI_DeleteObject($hbmpPic)

    [/autoit]


    Falls du aber eine füssige Animation suchst, bist du wahrscheinlich mit reinem GDI+ ohne Pic Control besser bedient. Pic Controls sind eher für statische Bilder gedacht ;).

  • Hey,
    danke, leider habe ich eine PNG auch als Hintergrund. Deswegen habe ich auch eine neue Funktion wo eine neue Gui als Child erstellt wird.
    Ich habe jetzt versucht mir es von meinem Label ab zu gucken, leider geht es auch nicht.
    Vielleicht fällt dir ja was ein.

    Spoiler anzeigen
    [autoit]

    Func _GuiCreateLabel($iHwnd, $iText, $iX, $iY, $iW, $iH, $iColor = 0xFFFFFF, $iSize = 10, $iAtribute = 0, $iFont = "Arial", $iWeight = 400)
    $iGui = GUICreate("", $iW, $iH, $iX, $iY, BitOR($WS_POPUP, $WS_VISIBLE), BitOR($WS_EX_MDICHILD, $WS_EX_LAYERED), $iHwnd)
    $iLabel = GUICtrlCreateLabel($iText, 2, 0, $iW, $iH, -1, $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetColor(-1, $iColor)
    GUICtrlSetFont(-1, $iSize, $iWeight, $iAtribute, $iFont, 4)
    GUISetBkColor(0xABCDEF, $iGui)
    _WinAPI_SetLayeredWindowAttributes($iGui, 0xABCDEF, 255)

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

    Return $iLabel
    EndFunc ;==>_GuiCreateLabel

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

    Func _GuiCreatePic($iHwnd, $iPic, $iX, $iY, $iW, $iH)
    $bImage_Pic = _GDIPlus_ImageLoadFromFile($iPic)

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

    $bWidth = _GDIPlus_ImageGetWidth($bImage_Pic)
    $bHeight = _GDIPlus_ImageGetHeight($bImage_Pic)

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

    $hbmpPic = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bImage_Pic)

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

    $iGui = GUICreate("", $iW - 1, $iH - 1, $iX, $iY, BitOR($WS_POPUP, $WS_CHILD, $WS_VISIBLE), $WS_EX_MDICHILD, $iHwnd)
    $iPic = GUICtrlCreatePic("", -1, -1, $bWidth + 1, $bHeight + 1, BitOR($SS_NOTIFY, $WS_CLIPSIBLINGS, $GUI_SS_DEFAULT_PIC))
    GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hbmpPic)

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

    Return $iGui
    EndFunc ;==>_GuiCreatePic

    [/autoit]


    mfg Freaky

  • Ja ist mir schon bewusst.
    Leider bin ich nicht der begabteste mit GDI+. Egal wie oft ich versucht habe was damit zu machen, ist es immer in die Hose gegangen. Und deswegen versuche ich GDI+ aus dem Weg zu gehen um mir das Leben leichter zu machen.
    Des weiterem muss ich das Bild ja verschieben z.B. laden lassen, dass ist mit den ganzen Controls mit WinMove viel einfacher als manch einer denken würde :)
    So, wie würde ich den jetzt bei meiner Funktion die Gui Transparent bekommen?
    mfg Freaky

  • Zitat

    So, wie würde ich den jetzt bei meiner Funktion die Gui Transparent bekommen?


    Mit ein paar Funktionen die wesentlich aufwendiger und komplizierter sind als der GDI+ Code der nötig wäre um das auch so zu machen...
    Wenn du unbedingt wissen willst wie das geht, dann kannst du ja mal dieses Script von mir anschauen mit dem man auf einem transparenten Fenster zeichnen kann.
    Ansonsten würde ich dir empfehlen das einfach mal mit GDI+ zu versuchen. Das ist nicht so kompliziert wie viele denken, und außerdem benutzt du ja jetzt schon jede Menge Funktionen aus dieser UDF.
    Falls du das nicht hinkriegst kann man dir hier auch helfen, dafür ist das Forum ja da ;).

  • Hey,
    dein Script is ja mal richtig lustig. Muss ich mal in der Schule verwenden wenn die unser Bildschirm jedem Zeigen um alles weg zu malen :D

    Ok, zurück zum Thema :D
    So wie du es gemacht hast, macht es die Funktion SetTransparentBitmap auch die schon seit etwas längerem im Internet rumschwirt.

    Spoiler anzeigen
    [autoit]

    Func SetTransparentBitmap($hGUI, $hImage, $iOpacity = 0xFF)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    _WinAPI_ReleaseDC(0, $hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($hGUI, 0, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
    EndFunc ;==>SetTransparentBitmap

    [/autoit]


    Leider funktioniert es damit irgend wie auch nicht :/

  • hier mal ein beispiel aus meiner script sammlung!

    Spoiler anzeigen
    [autoit]


    #Include <_Ani.au3>
    #include <GUIConstantsEx.au3>
    #include <GUIConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    ;#include <WINAPI.au3>

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

    #Region ### START Koda GUI section ###
    $pic = @ScriptDir & "\TEMP\construction_animated.gif"

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

    ;--$Parent = GUICreate("", 280, 375,-1,-1, $WS_POPUP + $WS_EX_LAYERED +0x00800000);270,137
    $Parent = GUICreate("", 320, 297,-1,-1, $WS_POPUP + $WS_EX_LAYERED +0x00800000);270,137
    GUISetBkColor(0xFFFFFF) ; setzt hintergrundfarbe
    $TRANSPARENCY = 0
    WinSetTrans($Parent,"",$TRANSPARENCY)
    GUISetState()

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

    ;--$pic2 = GUICtrlCreatePic($Scriptdir & "\" & $pic, 0, 0, 300, 350, BitOR(0x0100, $WS_GROUP, $WS_CLIPSIBLINGS))
    $pic2 = GUICtrlCreatePic($pic, 0, 0, 320, 297, BitOR(0x0100, $WS_GROUP, $WS_CLIPSIBLINGS))
    ;DllCall("uxtheme.dll", "none", "SetThemeAppProperties", "int", 7)

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

    ;--$labelversion = GUICtrlCreateLabel("Version 1.2.0.9", 0, 346, 280, 14, 0x01)
    $labelversion = GUICtrlCreateLabel("Version 1.2.1.2", 112, 260, 95, 14, 0x01)
    GUICtrlSetFont($labelversion, 8, 80, 0, "Arial")
    ;GUICtrlSetColor($labelversion, 0xF76E12)
    GUICtrlSetBkColor($labelversion, $GUI_BKCOLOR_TRANSPARENT)

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

    $label = GUICtrlCreateLabel("... Programm wird vorbereitet ...", -2, 274, 320, 13, 0x01)
    GUICtrlSetFont($label, 8, 80, 0, "Arial")
    GUICtrlSetBkColor($label, $GUI_BKCOLOR_TRANSPARENT)
    ;GUICtrlSetBkColor($label, $GUI_BKCOLOR_TRANSPARENT)
    ;GUICtrlSetBkColor($label, 0x000000)
    ;_WinAPI_SetLayeredWindowAttributes($Parent, 0xFFFFFF) ;setzt transparente farbe, hier weiß

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

    ;animiere gif derzeit auskommentiert ...
    ;$gif = GUICtrlCreateGifEx($Parent, $pic, 0, 0);no width/height, always automatic. --> erstelle gif picture
    ;_Ani_SetAnimationSpeed(1, $gif)

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

    GUISetState(@SW_SHOW)

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

    #EndRegion ### END Koda GUI section ###

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

    While 1

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

    WEnd

    [/autoit]

    vielleicht nützt es dir was :)

    gruß gmmg

  • Zitat

    Leider funktioniert es damit irgend wie auch nicht :/


    Interessante Fehlerbeschreibung... Wie wäre es wenn du es mit GDI+ machst? :rolleyes:

    Spoiler anzeigen
    [autoit]

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

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

    $iX = 50
    $iY = 15
    $iWidth = 300
    $iHeight = 50
    $iProgress = 0

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

    $sPath_ImageBG = @ScriptDir & "\BG.png"
    $sPath_ImageBar = @ScriptDir & "\Bar.png"

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

    $hWnd = GUICreate("Test", 400, 100)
    $cButton_Add = GUICtrlCreateButton("+10", 205, 70, 40, 20)
    $cButton_Sub = GUICtrlCreateButton("-10", 155, 70, 40, 20)
    GUISetState()

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

    _GDIPlus_Startup()

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

    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetClipRect($hGraphics, $iX, $iY, $iWidth, $iHeight)
    _GDIPlus_GraphicsSetSmoothingMode($hBuffer, 2)

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

    $hImageBG = _GDIPlus_ImageLoadFromFile($sPath_ImageBG)
    $hImageBar = _GDIPlus_ImageLoadFromFile($sPath_ImageBar)

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

    _DrawProgress($iProgress)

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

    OnAutoItExitRegister("_Shutdown")
    GUIRegisterMsg($WM_PAINT, "_ReDraw")

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

    While True
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    Case $GUI_EVENT_RESTORE
    _ReDraw()
    Case $cButton_Add
    If $iProgress < 100 Then
    $iProgress += 10
    _DrawProgress($iProgress)
    EndIf
    Case $cButton_Sub
    If $iProgress > 0 Then
    $iProgress -= 10
    _DrawProgress($iProgress)
    EndIf
    EndSwitch
    WEnd

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

    Func _DrawProgress($iPercent)
    _GDIPlus_GraphicsSetClipRect($hBuffer, 0, 0, $iWidth, $iHeight)
    _GDIPlus_GraphicsClear($hBuffer, 0xFFFFFFFF)
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hImageBG, 0, 0, $iWidth, $iHeight)

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

    _GDIPlus_GraphicsSetClipRect($hBuffer, 0, 0, $iWidth / 100 * $iPercent, $iHeight)
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hImageBar, 0, 0, $iWidth, $iHeight)

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

    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, $iX, $iY, $iWidth, $iHeight)
    EndFunc

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

    Func _Shutdown()
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_GraphicsDispose($hBuffer)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_ImageDispose($hImageBG)
    _GDIPlus_ImageDispose($hImageBar)
    _GDIPlus_Shutdown()
    EndFunc

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

    Func _ReDraw()
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, $iX, $iY, $iWidth, $iHeight)
    EndFunc

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

    ;-GDIP.au3 Functions:
    Func _GDIPlus_GraphicsSetClipRect($hGraphics, $nX, $nY, $nWidth, $nHeight, $iCombineMode = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetClipRect", "hwnd", $hGraphics, "float", $nX, "float", $nY, "float", $nWidth, "float", $nHeight, "int", $iCombineMode)

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

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

    [/autoit]


    Kopier mal die beiden Bilder im Anhang in das Scriptverzeichnis. Mit den Buttons kannst du die Progressbar steuern.
    Ist das wirklich so schwer?

  • Zitat

    Naja, ein Bild als Hintergrund habe ich bereits.


    Wie meinst du das? Ich hab ja auch nur ein Beispiel gemacht. Größe des Ladebalkens, verwendete Bilder, das lässt sich alles mit ein paar Variablen ändern. Ich dachte das wäre das wonach du suchst, wenn dem nicht so ist, wonach suchst du dann?