GDI+, nur schwarzes Bild! Wer kann helfen?

  • Hallo,

    kann mir jemand sagen wieso ich nur ein schwarzes Bild als Resultat bekomme?

    Spoiler anzeigen
    [autoit]

    #include <GuiConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GDIPlus.au3>
    #include <ScreenCapture.au3>
    #include <WinAPI.au3>
    Opt('MustDeclareVars', 1)
    Local $hBitmap, $hImage, $sImageType, $iX, $iY, $iXc, $iYc, $iMemo, $iPixelColor, $Count, $File, $color1, $oForm, $color, $dc, $setpixel, $realesedc
    Local $hGraphic, $hBitmap, $hBackbuffer, $save, $hPen, $hWind
    $color1 = 0x000000
    $File = FileOpen(@DesktopDir & "\coords.txt", 2)
    _Main()
    Func _Main()
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile(@DesktopDir & "\jdriscoll.jpg")
    $sImageType = _GDIPlus_EncodersGetCLSID("JPG")
    $iX = _GDIPlus_ImageGetWidth($hImage)
    $iY = _GDIPlus_ImageGetHeight($hImage)
    $oForm = GUICreate("GDI+", ($iX), ($iY))
    GUISetBkColor(0xFFFFFF)
    ;$iMemo = GUICtrlCreateEdit("", 0, 0, ($iX + 25), ($iY + 25))
    GUISetState()
    $hWind = WinGetHandle($oForm)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWind)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iX, $iY, $hGraphic)
    $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    ;PixelCount
    For $iXc = 0 To $iX - 1
    For $iYc = 0 To $iY - 1
    $iPixelColor = Hex(_GDIPlus_GetPixel($hImage, $iXc, $iYc), 6)
    If Dec($iPixelColor) < 3947582 Then
    $Count = $Count + 1
    FileWrite($File, $iXc & "," & $iYc & @CRLF)
    ;MemoWrite("X= " & $iXc & " / Y= " & $iYc)
    SetPixel($oForm, $iXc, $iYc, $color)
    $hPen = _GDIPlus_PenCreate(0x000000);
    _GDIPlus_GraphicsDrawLine ($hBackbuffer, $iXc, $iYc, $iXc + 1, $iYc + 1, $hPen)
    _GDIPlus_GraphicsDrawLine ($hGraphic, $iXc, $iYc, $iXc + 1, $iYc + 1, $hPen)
    EndIf
    Next
    Next

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

    $save = _GDIPlus_ImageSaveToFile($hBitmap,@ScriptDir & '\Image1.jpg')

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

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    FileClose($File)
    _GDIPlus_Shutdown()
    EndFunc ;==>_Main
    ; Gibt eine Zeile im Memo-Fenster aus
    Func MemoWrite($sMessage = '')
    GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
    EndFunc ;==>MemoWrite
    ; _GDIPlus_GetPixel
    Func _GDIPlus_GetPixel($hBitmap, $X, $Y)
    Local $result = DllCall($ghGDIPDLL, "int", "GdipBitmapGetPixel", "ptr", $hBitmap, "int", $X, "int", $Y, "dword*", 0)
    If @error Then Return SetError(1, 0, 0)
    Return SetError($result[0], 1, $result[4])
    EndFunc ;==>_GDIPlus_GetPixel
    ;SetPixel
    Func SetPixel($oForm, $X, $Y, $color)
    $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", $oForm)
    $setpixel = DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $X, "long", $Y, "long", $color)
    $realesedc = DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "int", $dc[0])
    EndFunc ;==>SetPixel

    [/autoit]
  • Wo soll ich da bloß anfangen...
    Also. GDIPlus verwendet das ARGB Farbsystem. Das heißt, du musst nicht nur die drei Farbkomponenten Rot, Grün, und Blau angeben, sondern auch noch den sogenannten AlphaChannel, welcher die Transparenz bestimmt.
    Wenn du nun eine neue leere Bitmap erstellst, völlig egal wie, hat standardmäßig jeder Pixel den Wert 0 (bzw. als Hexadezimal-ARGB Wert 0x00000000) 0x000000 entspricht der Farbe schwarz, und da der AlphaChannel auch den Wert 0 hat, ist der Pixel komplett transparent bzw. unsichtbar. Später willst du den Inhalt der Bitmap als JPEG Bild abspeichern. Das Problem dabei ist, dass JPEG keine Farbdaten mit AphaChannel unterstützt. Bei JPEG gibt es keine Transparenz, und deswegen weiß Windows gar nicht was es mit diesen Daten die offensichtlich nicht im JPEG Format sind machen soll. Daher das schwarze Bild. Du kannst nun entweder die leere Bitmap vorher komplett mit einer Farbe übermalen die einen Alpha Wert von 255 also 0xFF hat, oder du kannst das Bild in einem Format abspeichern, das Transparenz unterstützt, wie z.B. png.

  • OK, danke Euch!

    So siehts nun aus! Prima:

    Spoiler anzeigen
    [autoit]

    #include <GuiConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GDIPlus.au3>
    #include <ScreenCapture.au3>
    #include <WinAPI.au3>
    Opt('MustDeclareVars', 1)
    Local $hBitmap, $hImage, $sImageType, $iX, $iY, $iXc, $iYc, $iMemo, $iPixelColor, $Count, $File, $color1, $oForm, $color, $dc, $setpixel, $realesedc
    Local $hGraphic, $hBitmap, $hBackbuffer, $save, $hPen, $hWind
    $color1 = 0x000000
    $File = FileOpen(@DesktopDir & "\coords.txt", 2)
    _Main()
    Func _Main()
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile(@DesktopDir & "\jdriscoll.jpg")
    $sImageType = _GDIPlus_EncodersGetCLSID("JPG")
    $iX = _GDIPlus_ImageGetWidth($hImage)
    $iY = _GDIPlus_ImageGetHeight($hImage)
    $oForm = GUICreate("GDI+", ($iX), ($iY))
    GUISetBkColor(0xFFFFFF)
    ;$iMemo = GUICtrlCreateEdit("", 0, 0, ($iX + 25), ($iY + 25))
    GUISetState()
    $hWind = WinGetHandle($oForm)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWind)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iX, $iY, $hGraphic)
    $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFFFFFFFF)
    ;PixelCount
    For $iXc = 0 To $iX - 1
    For $iYc = 0 To $iY - 1
    $iPixelColor = Hex(_GDIPlus_GetPixel($hImage, $iXc, $iYc), 6)
    If Dec($iPixelColor) < 3947582 Then
    $Count = $Count + 1
    FileWrite($File, $iXc & "," & $iYc & @CRLF)
    ;MemoWrite("X= " & $iXc & " / Y= " & $iYc)
    SetPixel($oForm, $iXc, $iYc, $color)
    $hPen = _GDIPlus_PenCreate(0xFF000000);
    _GDIPlus_GraphicsDrawLine ($hBackbuffer, $iXc, $iYc, $iXc + 1, $iYc + 1, $hPen)
    _GDIPlus_GraphicsDrawLine ($hGraphic, $iXc, $iYc, $iXc + 1, $iYc + 1, $hPen)
    EndIf
    Next
    Next
    $save = _GDIPlus_ImageSaveToFile($hBitmap,@ScriptDir & '\Image1.jpg')
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    FileClose($File)
    _GDIPlus_Shutdown()
    EndFunc ;==>_Main
    ; Gibt eine Zeile im Memo-Fenster aus
    Func MemoWrite($sMessage = '')
    GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
    EndFunc ;==>MemoWrite
    ; _GDIPlus_GetPixel
    Func _GDIPlus_GetPixel($hBitmap, $X, $Y)
    Local $result = DllCall($ghGDIPDLL, "int", "GdipBitmapGetPixel", "ptr", $hBitmap, "int", $X, "int", $Y, "dword*", 0)
    If @error Then Return SetError(1, 0, 0)
    Return SetError($result[0], 1, $result[4])
    EndFunc ;==>_GDIPlus_GetPixel
    ;SetPixel
    Func SetPixel($oForm, $X, $Y, $color)
    $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", $oForm)
    $setpixel = DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $X, "long", $Y, "long", $color)
    $realesedc = DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "int", $dc[0])
    EndFunc ;==>SetPixel

    [/autoit]