Pixel auslesen

  • hi,

    ist es möglich in einer png/bmp die pixel von einer
    bestimmten Farbe/Punkt eines Pixel bis zu einem
    anderen bestimmten punkt/Farbe eines Pixels
    auszulesen.

    Also die Anzahl der pixel zwischen zwei bestimmten pixel
    innerhalb eines Bildes auszulesen, ohne es anzuzeigen.
    Ist das möglich, wenn ja wie?

    Danke im Voraus

  • EDIT:
    Da es für mich ne gute Übung ist, hier jetzt extrem(!) vereinfacht, wobei es eigentlich nicht wirklich schneller ist:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <AssembleIt.au3>

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

    ; ///////////////
    ;~ $_assembleit_flag = 0
    ;~ _assembleit("ptr", "_asm")
    ; \\\\\\\\\\\\\\\

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

    $timer = TimerInit()
    ConsoleWrite(_GetPixelCount('example.jpg', 0x00beb2, 0x3A5573) & @CRLF)
    ConsoleWrite(TimerDiff($timer) & @CRLF)

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

    Func _GetPixelCount($sPath, $iColor1, $iColor2)
    _GDIPlus_Startup()
    $hBitmap = _GDIPlus_BitmapCreateFromFile($sPath)
    If $hBitmap = 0 Then Return -1
    $iWidth = _GDIPlus_ImageGetWidth($hBitmap)
    $iHeight = _GDIPlus_ImageGetHeight($hBitmap)
    $iSize = $iWidth*$iHeight
    $hBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32RGB)

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

    Global $tCodeBuffer = DllStructCreate("byte[43]") ;reserve Memory for opcodes
    DllStructSetData($tCodeBuffer, 1,"0x8B7C24048B4C24088B44240C8B5C2410F2AF83F900741189CA89D8F2AF83F900740689C889D129C189C8C3") ;write opcodes into memory
    $ret=DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer),"ptr",DllStructGetData($hBitmapData, "Scan0"),"int",$iWidth*$iHeight,"int",0xFF000000 + $iColor1,"int",0xFF000000 + $iColor2)
    Return $ret[0]
    _GDIPlus_BitmapUnlockBits($hBitmap, $hBitmapData)
    EndFunc

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

    Func _asm()
    _("use32")
    _("mov edi, dword[esp + 4]") ; Pointer Bitmap
    _("mov ecx, dword[esp + 8]") ; ImageSize
    _("mov eax, dword[esp + 12]") ; erste Farbe
    _("mov ebx, dword[esp + 16]") ; zweite Farbe

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

    _("REPNE SCASD")
    _("cmp ecx, 0")
    _("jz _Return") ; Springe zu _Return, wenn ECX:0

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

    _("mov edx, ecx") ; Stack: (ImageSize-Position erste Farbe)

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

    _("mov eax, ebx")
    _("REPNE SCASD")
    _("cmp ecx, 0")
    _("je _Return") ; Springe zu _Return, wenn ECX:0

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

    _("mov eax, ecx") ; EAX: (ImageSize-Position zweite Farbe)
    _("mov ecx, edx") ; ECX: (ImageSize-Position erste Farbe)
    _("sub ecx, eax") ; ECX: Diff
    _("_Return:")
    _("mov eax, ecx") ; EAX: ECX
    _("ret")
    EndFunc

    [/autoit]
    Zitat

    You just keep on trying 'till you run out of cake. ;)


    [STEAM] Source UDF

    6 Mal editiert, zuletzt von K4z (12. April 2012 um 22:41)

  • Da ich grad eh nix zu tun hab, hier ein Versuch das nur in AutoIt umzusetzten:
    EDIT: Nochmal ordendlich Geschwindigkeit rausgeholt, aber immernoch ca 140x langsamer als der FASM Code...

    Spoiler anzeigen
    [autoit]

    Func _GetPixelCount($sPath, $iColor1, $iColor2)
    $iColor1 += 0xFF000000
    $iColor2 += 0xFF000000
    _GDIPlus_Startup()
    Local $iPos1 = 0, $iPos2 = 0
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sPath)
    If $hBitmap = 0 Then Return -1
    Local $iWidth = _GDIPlus_ImageGetWidth($hBitmap), $iHeight = _GDIPlus_ImageGetHeight($hBitmap), $iSize = $iWidth*$iHeight
    Local $hBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    Local $tPixels = DllStructCreate("dword["&$iSize&"]", DllStructGetData($hBitmapData, "Scan0"))
    For $iI = 0 To $iSize
    If Int(DllStructGetData($tPixels, 1, $iI), 1) = $iColor1 Then
    $iPos1 = $iI
    ExitLoop
    EndIf
    Next
    If $iPos1 = 0 Then
    _GDIPlus_BitmapUnlockBits($hBitmap, $hBitmapData)
    Return 0
    EndIf
    For $iI = $iPos1 To $iSize
    If Int(DllStructGetData($tPixels, 1, $iI), 1) = $iColor2 Then
    $iPos2 = $iI
    ExitLoop
    EndIf
    Next
    _GDIPlus_BitmapUnlockBits($hBitmap, $hBitmapData)
    If $iPos2 = 0 Then Return 0
    Return $iPos2-$iPos1
    EndFunc

    [/autoit]
    Zitat

    You just keep on trying 'till you run out of cake. ;)


    [STEAM] Source UDF

    Einmal editiert, zuletzt von K4z (12. April 2012 um 19:52)