Bild Scannen (Schwarz-Weiß) und alle Koordinaten der schwarzen Pixel in eine .ini schreiben

  • Bild mit

    [autoit]

    _GDIPlus_ImageLoadFromFile

    [/autoit]

    laden, und dann mit

    [autoit]

    _GDIPlus_BitmapLockBits

    [/autoit]

    auslesen. In der Hilfe zu BitmapLockBits ist ein Beispiel, wo ein Bild in sein Graustufenäquivalent umgewandelt wird. Im Prinzip musst du es nur so umschreiben, dass die Farbe der ausgelesenen Pixel mit 0x000000 verglichen wird und bei übereinstimmung die Koordinaten in ein Array eintragen.

  • Also das hier?

    Spoiler anzeigen
    [autoit]

    For $row = 0 To $Height - 1 ; Reihe für Reihe
    For $col = 0 To $Width - 1 ; Spalte für Spalte
    ; lese Farbinformation des aktuellen Pixels(Spalte,Reihe) aus
    $PixelData = DllStructCreate("dword", $Scan0 + ($row * $Stride) + ($col * 4))
    $Color = DllStructGetData($PixelData, 1)
    ; berechne Grauwert
    $Luma = _ColorGetRed($Color) * 0.3 + _ColorGetGreen($Color) * 0.59 + _ColorGetBlue($Color) * 0.11
    ; Rot Grün und Blau wert werden jeweils auf den berechneten Grauwert gesetzt
    DllStructSetData($PixelData, 1, BitOR($Luma, BitShift($Luma, -8), BitShift($Luma, -16)))
    Next
    Next

    [/autoit]
  • Zitat

    wi ersetze ich die varbiablen $Scan und $Stride dementsprechend?


    Wozu? Das einzige was du verändern musst, ist der Code zwischen Zeile 5 und 10. Z.B. so:

    [autoit]

    For $row = 0 To $Height - 1 ; Reihe für Reihe
    For $col = 0 To $Width - 1 ; Spalte für Spalte
    ; lese Farbinformation des aktuellen Pixels(Spalte,Reihe) aus
    $PixelData = DllStructCreate("dword", $Scan0 + ($row * $Stride) + ($col * 4))
    $Color = DllStructGetData($PixelData, 1)
    If $Color = 0 Then
    $xPixel = $row
    $yPixel = $col
    EndIf
    DllStructSetData($PixelData, 1, BitOR($Luma, BitShift($Luma, -8), BitShift($Luma, -16)))
    Next
    Next

    [/autoit]


    Statt die Werte in $xPixel etc. zu speichern, speicherst du sie dann eben in einem Array, oder einer ähnlichen Datenstruktur.

  • sry, dass ich das noch nich so versteh, ich fang erst seit heute an mit GDI+... ehm ich hab schon ein bild was nur schwarze oder weiße pixel hat gespeichert. wie verarbeite ich das so, dass ichs als die Scan variable nehmen kann?

    EDIT: Geht das nicht auch mit PixelSearch()?

  • Zitat

    Geht das nicht auch mit PixelSearch()?


    Das wäre die schlechteste Methode die du benutzen könntest...

    Zitat

    wie verarbeite ich das so, dass ichs als die Scan variable nehmen kann?


    Indem du den ganzen Code betrachtest, und nicht nur die For Schleife? Den Teil in der For Schleife musst du anpassen, aber ohne den Rest funktioniert das ganze natürlich nicht.
    Du musst einfac nur das geladene Bild (_ImageLoadFromFile) bei dem BitmapLockBits Befehl einsetzen.

  • ok das skript sieht bei mir jezz so aus und läuft nicht :P

    Spoiler anzeigen
    [autoit]

    #include <GuiConstants.au3>
    #include <GdiPlus.au3>
    #include <Misc.au3>
    #include <Color.au3>

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

    $file = FileOpenDialog("SnakeLvLEditor", @DesktopDir &"\Eigene Programme\Snake", "Bilder (*.jpg)")
    $iniFile = StringReplace($file, ".jpg", ".ini")

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

    _GDIPlus_Startup()

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

    $hBmp = _GDIPlus_ImageLoadFromFile($file)
    $height = _GDIPlus_ImageGetHeight($hBmp)
    $width = _GDIPlus_ImageGetWidth($hBmp)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp) ; erstelle ein Bitmap aus Screenshot zur Verwendung mit GDI+
    $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; erstelle Grafikhandle um auf dem Bitmap zu zeichnen

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

    Local $BitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $width, $height, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32RGB)
    Local $Stride = DllStructGetData($BitmapData, "Stride") ; Stride ist der Offset von einer Reihe zur nächsten
    Local $Scan0 = DllStructGetData($BitmapData, "Scan0") ; Die Bilddaten im Speicher
    Local $PixelData
    For $row = 0 To $height - 1 ; Reihe für Reihe
    For $col = 0 To $width - 1 ; Spalte für Spalte
    ; lese Farbinformation des aktuellen Pixels(Spalte,Reihe) aus
    $PixelData = DllStructCreate("dword", $Scan0 + ($row * $Stride) + ($col * 4))
    $Color = DllStructGetData($PixelData, 1)
    If $Color = 0 Then
    IniWrite($iniFile, "Pixel", $row, $col)
    EndIf
    Next
    Next
    _GDIPlus_BitmapUnlockBits($hBitmap, $BitmapData)

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

    _GDIPlus_Shutdown()
    MsgBox(0,"","fertig")

    [/autoit]
  • ... Man sollte meinen, das die Kommentare als Beschreibung ausreichen...
    Willst du dein Bild auslesen oder einen Screenshot der nicht existiert?

    Spoiler anzeigen
    [autoit]

    #include <GuiConstants.au3>
    #include <GdiPlus.au3>
    #include <Misc.au3>
    #include <Color.au3>

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

    $file = FileOpenDialog("SnakeLvLEditor", @DesktopDir &"\Eigene Programme\Snake", "Bilder (*.jpg)")
    $iniFile = StringReplace($file, ".jpg", ".ini")

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

    _GDIPlus_Startup()

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

    $hBitmap = _GDIPlus_BitmapCreateFromFile($file)
    $height = _GDIPlus_ImageGetHeight($hBitmap)
    $width = _GDIPlus_ImageGetWidth($hBitmap)

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

    Local $BitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $width, $height, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    Local $Stride = DllStructGetData($BitmapData, "Stride") ; Stride ist der Offset von einer Reihe zur nächsten
    Local $Scan0 = DllStructGetData($BitmapData, "Scan0") ; Die Bilddaten im Speicher
    Local $PixelData
    For $row = 0 To $height - 1 ; Reihe für Reihe
    For $col = 0 To $width - 1 ; Spalte für Spalte
    ; lese Farbinformation des aktuellen Pixels(Spalte,Reihe) aus
    $PixelData = DllStructCreate("dword", $Scan0 + ($row * $Stride) + ($col * 4))
    $Color = DllStructGetData($PixelData, 1)
    If $Color = 0 Then
    IniWrite($iniFile, "Pixel", $row, $col)
    EndIf
    Next
    Next
    _GDIPlus_BitmapUnlockBits($hBitmap, $BitmapData)

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

    _GDIPlus_Shutdown()
    MsgBox(0,"","fertig")

    [/autoit]
  • oben muss man ja ein .jpg bild auswählen und das wird ausgelesen und es sollen alle Koordinaten der schwarzen Pixel aus dem Bild in einer .ini gespeichert werden. Ich raff halt die DLLs nich. Gibts da keinen Befehla ls ersatz O.o

  • Zitat

    Gibts da keinen Befehla ls ersatz O.o


    Nicht bei den internen Funktionen, und in den Standard UDFs ist so etwas auch nicht. Wozu auch? Es wird erwartet, dass du dir deine Befehle selbst erstellst. Oder würdest du als AutoIt Entwickler jede kleine Funktion die man möglicherweise nur in einem Script verwenden kann sofort als Standard Funktion aufnehmen?

  • Welche DLL? Es geht hier um ein DLL Struct. Stell es dir vor wie eine Ini Datei im Arbeitsspeicher. Die Funktion BitmapLockBits gibt ein DLLStruct, das die gesamten Farbdaten der Bitmap enthält zurück (und zwar in einer $tagGDIPBITMAPDATA Struktur). Was in dieser Struktur wo gespeichert ist, findest du in der Hilfe unter $tagGDIPBITMAPDATA. Wie du die Daten ausliest erfährst du aus dem Beispiel zu LockBits, oder auch aus der Hilfe zu DllStructGetData bzw. DllStructCreate.

  • hab mir jezz mal alle Infos durchgelesen und langsam versteh ich es ;D danke ich schau mir den rest des abends einfach weiter tuts an und schreibe morgen weiter...

    EDIT: Letzte Frage noch: ich brauch doch nur 1Bit also $GDIP_PXF01INDEXED, weil das Bild doch nur in Schwarz weiß existiert oder?

  • ok ich habs doch noch heute gemacht :D

    irgendwas geht nicht aber ich weiß nich was (sonst würd ichs ja nicht schrieben^^)

    Spoiler anzeigen
    [autoit]

    #include <GuiConstants.au3>
    #include <GdiPlus.au3>
    #include <Misc.au3>
    #include <Color.au3>

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

    $file = FileOpenDialog("SnakeLvLEditor", @DesktopDir &"\Eigene Programme\Snake", "Bilder (*.jpg)")
    $iniFile = StringReplace($file, ".jpg", ".ini")

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

    _GDIPlus_Startup()

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

    $hBmp = _GDIPlus_ImageLoadFromFile($file)
    $PicWidth = _GDIPlus_ImageGetWidth($file)
    $PicHeight = _GDIPlus_ImageGetWidth($file)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp) ; erstelle ein Bitmap aus Screenshot zur Verwendung mit GDI+
    _WinAPI_DeleteObject($hBmp) ; lösche Screenshot aus Speicher

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

    _GreyScale($hBitmap, 0, 0, $PicWidth, $PicHeight) ; Bereich wird in Graustufen umberechnet

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

    _GDIPlus_BitmapDispose($hBitmap) ; lösche Bild aus dem Speicher
    _GDIPlus_Shutdown()

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

    Func _GreyScale($hBitmap, $iX, $iY, $iW, $iH)
    Local $BitmapData = _GDIPlus_BitmapLockBits($hBitmap, $iX, $iY, $iW, $iH, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32RGB)
    Local $Stride = DllStructGetData($BitmapData, "Stride") ; Stride ist der Offset von einer Reihe zur nächsten
    Local $Width = DllStructGetData($BitmapData, "Width") ; Anzahl der Spalten
    Local $Height = DllStructGetData($BitmapData, "Height") ; Anzahl der Reihen
    Local $Scan0 = DllStructGetData($BitmapData, "Scan0") ; Die Bilddaten im Speicher
    Local $PixelData, $Color, $Luma
    For $row = 0 To $Height - 1 ; Reihe für Reihe
    For $col = 0 To $Width - 1 ; Spalte für Spalte
    ; lese Farbinformation des aktuellen Pixels(Spalte,Reihe) aus
    $PixelData = DllStructCreate("dword", $Scan0 + ($row * $Stride) + ($col * 4))
    $Color = DllStructGetData($PixelData, 1)
    IniWrite($iniFile, "Pixel", $row, $col)
    Next
    Next
    _GDIPlus_BitmapUnlockBits($hBitmap, $BitmapData)
    EndFunc ;==>_GreyScale

    [/autoit]