Bestimmte Farbe in einem Bild transparent machen

  • Ich bins wieder :P

    Und diesmal mit folgendem Problem:
    Ich hab ein Bild (Anhang), indem manche Teile rot sind (0xFF0000).
    Die roten Teile will ich transparent erscheinen lassen.
    Das Bild wird mit GDi+ gezeichnet (also eine Graphik).

    Mit der SuFu hab ich nicht wirklich was brauchbares gefunden. :(

    Ich Danke euch schonmal für die Antworten. :)

    MfG
    H2112

    PS: Script:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GuiConstantsEx.au3>
    #Include <WinAPI.au3>
    #include <Array.au3>

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

    _GDIPlus_Startup()

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

    Global $hImage = _GDIPlus_BitmapCreateFromFile("DieWelt.png")
    Global $hBitmapWidht = _GDIPlus_ImageGetWidth($hImage), $hBitmapHeight = _GDIPlus_ImageGetHeight($hImage), $PicZahl = $hBitmapWidht / 16 * $hBitmapHeight / 16
    Global $hBitmap, $hGraphic, $hGUI, $hImage, $hSplit[$PicZahl]

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

    Global $Widht = 0, $High = 0

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

    $hGUI = GUICreate("Bildteiler", 580 + $hBitmapWidht / 16, 356 + $hBitmapHeight / 16)
    GUISetBkColor(0x00FF00, $hGUI)
    GUISetState()

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

    For $i = 0 To $PicZahl -1 Step + 1
    If $Widht <> $hBitmapWidht Then
    $hSplit[$i] = _GDIPlus_BitmapCloneArea($hImage, $Widht, $High, 16, 16)
    $Widht = $Widht + 16
    Else
    $Widht = 0
    $High = $High + 16
    $i = $i - 1
    EndIf
    Next

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

    $Widht = 0
    $High = 0

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

    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    For $i = 0 To $PicZahl -1 Step + 1
    If $Widht <> $hBitmapWidht + $hBitmapWidht / 16 Then
    _GDIPlus_GraphicsDrawImage($hGraphic, $hSplit[$i], 50 + $Widht, 50 + $High)
    $Widht = $Widht + 16 + 1
    Else
    $Widht = 0
    $High = $High + 16 + 1
    $i = $i - 1
    EndIf
    Next

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

    $Widht = 0
    $High = 0

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

    Do
    For $i = 0 To $PicZahl -1 Step + 1
    If $Widht <> $hBitmapWidht + $hBitmapWidht / 16 Then
    _GDIPlus_GraphicsDrawImage($hGraphic, $hSplit[$i], 50 + $Widht, 50 + $High)
    $Widht = $Widht + 16 + 1
    Else
    $Widht = 0
    $High = $High + 16 + 1
    $i = $i - 1
    EndIf
    Next
    $Widht = 0
    $High = 0
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

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

    _GDIPlus_GraphicsDispose($hGraphic)
    _WinAPI_DeleteObject($hImage)

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

    _GDIPlus_Shutdown()

    [/autoit]
    Zitat

    [Heute, 11:39] Raupi: Soll ich es dir machen?
    [Heute, 11:47] BugFix: "Soll ich es dir machen? " - also Raupi !! bitte nicht so öffentlich :rofl:

    Zitat

    [Heute, 11:51] BugFix: und ich werde es mir jetzt machen - das Mittagessen :P

    AMsg UDF v1.00.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%
    OwnStyle UDF Version 1.10.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%

  • Ich weis zwar nicht wie man das umstellen kann, aber soweit ich weis ist Rosa der Standart für durchsichtig. Weis aber nicht welcher Farbcode das genau ist.

    Mfg

    Computers are like Airconditioning. They don´t work with open Windows.

  • Die GUI selbst soll ja nicht transparent sein. :)
    Und durch deine Methode werden die Bilder viel zu groß. ;P Und es sollen ja über 50 von diesen Bildern mitgepackt werden. Das wäre zu große Platzversschändung...

    Und das mit rosa, kann ich nicht bestätigen. :/
    Die Farbe bleibt (wenn sie reines rosa ist) rosa. Vll ist es aber auch nicht der korrekte Farbcode...

    Zitat

    [Heute, 11:39] Raupi: Soll ich es dir machen?
    [Heute, 11:47] BugFix: "Soll ich es dir machen? " - also Raupi !! bitte nicht so öffentlich :rofl:

    Zitat

    [Heute, 11:51] BugFix: und ich werde es mir jetzt machen - das Mittagessen :P

    AMsg UDF v1.00.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%
    OwnStyle UDF Version 1.10.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%

  • Ich hab diese beiden Funktionen gefunden:

    Spoiler anzeigen
    [autoit]

    ;================Macht den Hintergrund Transparent, überall wo die farbe des pixels 1,1 ist===============
    Func ImageMakeTransparentBkGnd($hImage2, $GuiSizeX, $GuiSizeY)
    Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0, $v_Buffer, $v_Value, $iColor

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

    $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage2, 0, 0, $GuiSizeX, $GuiSizeY, $GDIP_PXF32ARGB)

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

    $iColor = GDIPlus_BitmapGetPixel($hBitmap1, 1, 1) ; Transparent color

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

    $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $GuiSizeX, $GuiSizeY, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)

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

    ;Get the returned values of _GDIPlus_BitmapLockBits ()
    $width = DllStructGetData ($Reslt, "width")
    $height = DllStructGetData($Reslt, "height")
    $stride = DllStructGetData($Reslt, "stride")
    $format = DllStructGetData($Reslt, "format")
    $Scan0 = DllStructGetData ($Reslt, "Scan0")

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

    For $i = 0 To $GuiSizeX - 1
    For $j = 0 To $GuiSizeY - 1
    $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4))
    $v_Value = DllStructGetData($v_Buffer, 1)
    If Hex($v_Value, 6) = Hex($iColor, 6) Then
    DllStructSetData($v_Buffer, 1, Hex($iColor, 6))
    EndIf
    Next
    Next

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

    _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt)

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

    Return $hBitmap1
    EndFunc ;==>ImageMakeTransparentBkGnd

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

    ;The GetPixel method gets the color of a specified pixel in this bitmap.
    Func GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
    Local $tArgb, $pArgb, $aRet
    $tArgb = DllStructCreate("dword Argb")
    $pArgb = DllStructGetPtr($tArgb)
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "ptr", $pArgb)
    Return "0x" & Hex(DllStructGetData($tArgb, "Argb"))
    EndFunc ;==>GDIPlus_BitmapGetPixel

    [/autoit]

    Nur ich verstehe nich wirklich, was sie machen. :/

    Könnte mir da vieleicht wer auf die Sprünge helfen? :D

    Zitat

    [Heute, 11:39] Raupi: Soll ich es dir machen?
    [Heute, 11:47] BugFix: "Soll ich es dir machen? " - also Raupi !! bitte nicht so öffentlich :rofl:

    Zitat

    [Heute, 11:51] BugFix: und ich werde es mir jetzt machen - das Mittagessen :P

    AMsg UDF v1.00.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%
    OwnStyle UDF Version 1.10.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%

  • Ich habs jetzt auch mit Child Fenstern und _WinApiSetLayerWindowAttributes() versucht.
    Jetzt ist zwar der Hintergrund transparent die roten Teile im Bild aber nicht. :/

    Jetztiger Code:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GuiConstantsEx.au3>
    #Include <WinAPI.au3>

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

    _GDIPlus_Startup()

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

    Global $hImage = _GDIPlus_BitmapCreateFromFile("DieWelt.png")
    Global $hBitmapWidht = _GDIPlus_ImageGetWidth($hImage), $hBitmapHeight = _GDIPlus_ImageGetHeight($hImage), $PicZahl = $hBitmapWidht / 16 * $hBitmapHeight / 16
    Global $hBitmap, $hGraphic, $hGUI, $hImage, $hSplit[$PicZahl]
    Global $Widht = 0, $High = 0

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

    $hGUI = GUICreate("RPG Maker", 580 + $hBitmapWidht / 16, 356 + $hBitmapHeight / 16, @DesktopWidth / 2 - (580 + $hBitmapWidht / 16) / 2, @DesktopHeight / 2 - (356 + $hBitmapHeight / 16) / 2)
    GUISetBkColor(0xFF00FF, $hGUI)
    GUISetState()

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

    $Child1 = GUICreate("Child1", 580 + $hBitmapWidht / 16, 356 + $hBitmapHeight / 16, @DesktopWidth / 2 - (580 + $hBitmapWidht / 16) / 2 + 3, @DesktopHeight / 2 - (356 + $hBitmapHeight / 16) / 2 + 28, 0x80000000, BitOr(0x00080000 , 0x00000080), $hGUI)
    GUISetState()
    GUISetBkColor(0xFF0000, $Child1)

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

    $Child2 = GUICreate("Child2", 580 + $hBitmapWidht / 16, 356 + $hBitmapHeight / 16, @DesktopWidth / 2 - (580 + $hBitmapWidht / 16) / 2 + 3, @DesktopHeight / 2 - (356 + $hBitmapHeight / 16) / 2 + 28, 0x80000000, BitOr(0x00080000 , 0x00000080), $hGUI)
    GUISetState()
    GUISetBkColor(0xFF0000, $Child2)

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

    $hGraphic1 = _GDIPlus_GraphicsCreateFromHWND($Child1)
    $hGraphic2 = _GDIPlus_GraphicsCreateFromHWND($Child2)

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

    For $i = 0 To $PicZahl -1 Step + 1
    If $Widht <> $hBitmapWidht Then
    $hSplit[$i] = _GDIPlus_BitmapCloneArea($hImage, $Widht, $High, 16, 16)
    $Widht = $Widht + 16
    Else
    $Widht = 0
    $High = $High + 16
    $i = $i - 1
    EndIf
    Next

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

    $Widht = 0
    $High = 0

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

    Do
    _Multi_WinAPI_SetLayeredWindowAttributes()
    _DrawMultiMap(0, 0, 10, 20, 190, 1)
    _DrawMap(10, 9, 348, 2)
    _DrawMap(10, 10, 378, 2)
    _DrawMap(10, 11, 408, 2)
    _DrawMap(10, 12, 438, 2)
    _MoveChilds()
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

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

    _GDIPlus_Shutdown()

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

    Func _DrawMultiMap($XPos, $YPos, $MapHigh, $MapWidth, $Pic, $Layer)
    For $i = $XPos To $MapHigh + $XPos Step + 1
    For $j = $YPos To $MapWidth + $YPos Step + 1
    _DrawMap($i, $j, $Pic, 1)
    Next
    Next
    EndFunc

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

    Func _DrawMap($Position1, $Position2, $Pic, $Layer)
    If $Layer = 1 Then _GDIPlus_GraphicsDrawImage($hGraphic1, $hSplit[$Pic], $Position1 * 16, $Position2 * 16)
    If $Layer = 2 Then _GDIPlus_GraphicsDrawImage($hGraphic2, $hSplit[$Pic], $Position1 * 16, $Position2 * 16)
    EndFunc

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

    Func _MoveChilds()
    Local $hGUIPos1, $hGUIPos2
    $hGUIPos1 = WinGetPos("RPG Maker")
    $hGUIPos2 = WinGetPos("Child1")
    If $hGUIPos1[0] <> $hGUIPos2[0] Or $hGUIPos1[1] <> $hGUIPos2[1] Then
    WinMove("Child1", "", $hGUIPos1[0] + 3, $hGUIPos1[1] + 28)
    WinMove("Child2", "", $hGUIPos1[0] + 3, $hGUIPos1[1] + 28)
    EndIf
    EndFunc

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

    Func _WinAPI_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $dwFlages = 0x03, $isColorRef = False)
    ;progandy
    If $dwFlages = Default Or $dwFlages = "" Or $dwFlages < 0 Then $dwFlages = 0x03
    If Not $isColorRef Then
    $i_transcolor = Hex(String($i_transcolor), 6)
    $i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))
    EndIf
    Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $hwnd, "long", $i_transcolor, "byte", $Transparency, "long", $dwFlages)
    Select
    Case @error
    Return SetError(@error, 0, 0)
    Case $Ret[0] = 0
    Return SetError(4, _WinAPI_GetLastError(), 0)
    Case Else
    Return 1
    EndSelect
    EndFunc ;==>_WinAPI_SetLayeredWindowAttributes

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

    Func _Multi_WinAPI_SetLayeredWindowAttributes()
    _WinAPI_SetLayeredWindowAttributes($Child1, 0xFF0000)
    _WinAPI_SetLayeredWindowAttributes($Child2, 0xFF0000)
    EndFunc

    [/autoit]
    Zitat

    [Heute, 11:39] Raupi: Soll ich es dir machen?
    [Heute, 11:47] BugFix: "Soll ich es dir machen? " - also Raupi !! bitte nicht so öffentlich :rofl:

    Zitat

    [Heute, 11:51] BugFix: und ich werde es mir jetzt machen - das Mittagessen :P

    AMsg UDF v1.00.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%
    OwnStyle UDF Version 1.10.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%

  • Was tust du dir nur an? Transparent ist das PNG auch nicht größer als mit der roten Farbe ;)
    Mit GIMP in höchster Kompressionsstufe + Optipng wird es sogar kleiner (53161 Bytes statt 53990 Bytes) :D

  • Ich habs ja auch mit der transparents versucht.
    Da wird der transparente Fleck aufeinmal blau. :(

    Ergebnis ist im Anhang...

    Und irgendwie muss das ja gehen...

    Edit: 100 Beiträge! xD

    Edit2:
    Im Englischem Forum hab ich das gefunden:
    http://www.autoitscript.com/forum/index.php?showtopic=89702

    :/

    Zitat

    [Heute, 11:39] Raupi: Soll ich es dir machen?
    [Heute, 11:47] BugFix: "Soll ich es dir machen? " - also Raupi !! bitte nicht so öffentlich :rofl:

    Zitat

    [Heute, 11:51] BugFix: und ich werde es mir jetzt machen - das Mittagessen :P

    AMsg UDF v1.00.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%
    OwnStyle UDF Version 1.10.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%

    4 Mal editiert, zuletzt von H2112 (10. August 2009 um 16:22)

  • Ich würde die Bilder in etwa so zeichnen, dann funktioniert auch die TRansparenz und man muss sich um weniger GDI+-Bitmaps kümmern ;)

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GuiConstantsEx.au3>
    #Include <WinAPI.au3>
    #include <Array.au3>

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

    _GDIPlus_Startup()

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

    Global $hImage = _GDIPlus_ImageLoadFromFile(@DesktopDir&"\DieWelt.png")
    Global $hBitmapWidht = _GDIPlus_ImageGetWidth($hImage), _
    $hBitmapHeight = _GDIPlus_ImageGetHeight($hImage), _
    $iPicCountX = Floor($hBitmapWidht / 16) , _
    $iPicCountY = Floor($hBitmapHeight / 16) , _
    $PicZahl = $hBitmapWidht / 16 * $hBitmapHeight / 16
    Global $hGraphic, $hGUI

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

    Global $Widht = 0, $High = 0

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

    $hGUI = GUICreate("Bildteiler", 580 + $hBitmapWidht / 16, 356 + $hBitmapHeight / 16)
    GUISetBkColor(0x00FF00, $hGUI)
    GUISetState()

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

    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    For $y = 0 To $iPicCountY-1
    For $x = 0 To $iPicCountX-1
    _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hImage, $x*16, $y*16, 16, 16, 50 + $x*16+$x, 50 + $y*16+$y, 16, 16)
    Next
    Next

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

    $Widht = 0
    $High = 0

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

    Do
    For $y = 0 To $iPicCountY-1
    For $x = 0 To $iPicCountX-1
    _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hImage, $x*16, $y*16, 16, 16, 50 + $x*16+$x, 50 + $y*16+$y, 16, 16)
    Next
    Next
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

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

    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hImage)

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

    _GDIPlus_Shutdown()

    [/autoit]


    (als Bild hab ich das transparente von mir genommen)

  • Danke, du hast mein Leben gerettet. :D

    Dafür bekommst du nen fetten Eintrag in die Credits. ^^

    Zitat

    [Heute, 11:39] Raupi: Soll ich es dir machen?
    [Heute, 11:47] BugFix: "Soll ich es dir machen? " - also Raupi !! bitte nicht so öffentlich :rofl:

    Zitat

    [Heute, 11:51] BugFix: und ich werde es mir jetzt machen - das Mittagessen :P

    AMsg UDF v1.00.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%
    OwnStyle UDF Version 1.10.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%