Pixel eines Bildes auslesen ohne es darzustellen

  • sry, Fehler von mir!^^
    Die bmp-Datei wird idR "Bottom Up" gespeichert, d.h. die unterste Zeile als erstes usw...Diese Info erhält man aus dem Header.
    Ich ändere das Script im laufe des Tages ab, so dass es bei dir "passt"

  • Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <GDIPlus.au3>
    $bytes = FileRead("bg_1.bmp") ;alle Bytes lesen

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

    $width = 640 ;breite bmp
    $height = 482 ;höhe bmp

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

    Dim $array[483][641] ;array für alle pixel

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

    $t = TimerInit()
    For $x = 1 To 640 ;x-koordinate pixel
    For $y = 1 To 482 ;y-koordinate pixel
    $array[$y][$x] = Hex(Asc(StringMid($bytes, $width * $height - $width * $y + $x + 1078, 1)), 2) ;farbe in hex
    Next
    Next
    $m = TimerDiff($t)
    MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$m' & @LF & @LF & 'Return:' & @LF & $m) ;### Debug MSGBOX

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

    _ArrayDisplay($array)

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

    _GDIPlus_Startup()
    ;bissl GDI
    $hgui = GUICreate("Bildermaler", 640, 482)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hgui)
    GUISetState()
    For $x = 1 To 640 ;x-koordinate pixel
    For $y = 1 To 482 ;y-koordinate pixel
    Switch $array[$y][$x] ;den "Farben" in der Datei die richtigen Farbcodes zuweisen
    Case "00"
    $color = 0xFF000000
    Case "01"
    $color = 0xFFFF0000
    Case "02"
    $color = 0xFF00FF00 ;ich hab die hier mal grün gemacht^^
    Case "03"
    $color = 0xFFFFFFFF
    EndSwitch
    $hpen = _GDIPlus_PenCreate($color)
    _GDIPlus_GraphicsDrawEllipse($hGraphic, $x, $y, 1, 1, $hpen)
    _GDIPlus_PenDispose($hpen)
    Next
    Next

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

    Do
    Until GUIGetMsg() = -3

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

    ;die formel für die farbe lautet also
    $color = Hex(Asc(StringMid($bytes, 640 * 482 - 640 * $y + $x + 1078, 1)), 2)

    [/autoit]

    sodele, nun funktionierts
    Du musst beachten, daß die Farben noch nicht "transformiert" sind, dafür sind die 1024 Byte Farbtabelle da. Ich habe im "Bildermaler" die Farbcodes aus der Datei, z.B. 03 mal in weiß, und den Farbcode 01 der Farbe Rot zugeordnet

    ;Hausaufgabe für dich!
    ;Erstelle Anhand der Daten im Header eine allgemeine Formel, um aus jeder *.BMP-Datei die Farbe eines Pixels mit gegebener x- und y-Koordinate herauszufinden^^

    //edit// Noch nen "Bildermaler" hinzugefügt^^ . Das geht natürlich mit bitblt Millionen mal schneller, aber so sieht man was passiert

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    4 Mal editiert, zuletzt von Andy (12. Juli 2010 um 17:43)

  • Kein Thema :)
    Wenn du WIRKLICH unter die Hardliner gehen willst, dann mußt du den String=Dateiinhalt nichtmal laden, sondern kannst nur ein einzelnes Byte direkt aus der Datei lesen.
    Vergleich: Pixelfarbe lesen mit GDI+ dauert ca 25x länger auf meinem Rechner! Vorteil hierbei, bei Bitmaps, welche Farbtabellen mitliefern, ist die Umwandlung in RGB inclusive. Wobei man beim direkten Lesen der Bytes bei "normalen" BMP´s die Farbe direkt aus der Struct auslesen kann, also 25x schneller ist somit eine Ansage, wenn es auf Geschwindigkeit ankommt!

    Spoiler anzeigen
    [autoit]

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

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

    $t=timerinit()
    $tBuffer = DllStructCreate("byte") ;ein Byte Speicherverbrauch für die Farbe...verkraftbar :o)
    local $nbytes ;variable byref anzahl gelesener bytes aus der datei
    $hfile = _WinAPI_CreateFile("bg_1.bmp",2,2) ;Datei lesend öffnen
    $x = 243
    $y = 87

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

    $t=timerinit()
    _WinAPI_SetFilePointer($hfile,640 * 482 - 640 * $y + $x + 1078) ;filepointer auf position des bytes setzen
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), 1, $nBytes) ;byte lesen
    $color=dllstructgetdata($tbuffer,1)
    $m=timerdiff($t)

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

    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $color = ' & $color & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $m = ' & $m & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    _WinAPI_CloseHandle($hFile)

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

    ;gdi+, 20x langsamer, aber liefert dafür die farbe direkt in RGB
    _GDIPlus_Startup ()
    $hbitmap=_GDIPlus_ImageLoadFromFile("bg_1.bmp")
    ;global $ghGDIPDLL=dllopen("gdi_plus.dll")
    $t=timerinit()
    $color=hex(_GDIPlus_GetPixel($hbitmap,$x,$y),6)
    $m=timerdiff($t)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $color = ' & $color & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $m = ' & $m & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

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

    Func _GDIPlus_GetPixel($hBitmap,$X,$Y)
    ; Prog@ndy
    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

    [/autoit]

    /edit/ ohne winapi

    [autoit]

    $x=243
    $y=87

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

    $hfile=fileopen("bg_1.bmp",16)
    filesetpos($hfile,640 * 482 - 640 * $y + $x + 1078,0)
    $col=dec(hex(fileread($hfile,1)))
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $col = ' & $col & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    fileclose($hfile)

    [/autoit]

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (13. Juli 2010 um 18:37)