1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Andy

Beiträge von Andy

  • Verschiedene GDI+ Grafiken zeichnen und verschieben

    • Andy
    • 18. Dezember 2009 um 15:30

    so wie ich das verstehe meint er eine Funktion analog zu

    [autoit]

    controlmove()

    [/autoit]

    @Jautois
    Der große Vorteil von GDI+ ist die einfache Darstellung von Bildern, Pixeln, Zeichnungen über fertige Funktionen.
    Für Vorhaben, für die es keine fertige Funktion gibt, wie z.B. dein "Spritemove", musst du das bei GDI+ selbst in die Hand nehmen.
    Das Problem für die meisten ist, daß es nur eine einzige "Leinwand" gibt, auf der alle Operationen stattfinden.
    Für Deinen "Spritemove" nun die Vorgehensweise in Pseudocode:
    1. Hintergrund zeichnen
    Für eine "Bewegung" des Sprites ist es wichtig, den Hintergrund an der Spriteposition zu sichern! Denn der wird überschrieben, sobald du an dieser Position das Sprite zeichnest. Wenn dein Sprite sich "über" den Hintergrung bewegen soll, dann ist das eine Folge von Hintergrund zeichnen, Sprite an neuer Position zeichnen, Hintergrund zeichnen, Sprite an neuer Position zeichnen, uswusf
    Das schnelle "Zeichnen" auf den Hintergrund geht wunderbar mittels BitBlt (blitten), dabei wird ein Speicherbereich (dein Sprite) an eine andere Position im Speicher (den Hintergrund) verschoben. vgl (

    [autoit]

    _WinAPI_BitBlt()
    _GDIPlus_GraphicsDrawImageRectRect () ;der gdi+ "wrapper" zu bitblt

    [/autoit]

    )

    Beispiel aus der Hilfe ein bissl aufgepeppt und verschiedene Techniken gezeigt: Bitte mit Scite im Fullscreen ausführen (wg des AutoItlogos^^)

    Spoiler anzeigen
    [autoit]

    #include <GuiConstantsEx.au3>
    #include <GDIPlus.au3>
    #include <ScreenCapture.au3>

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

    Opt('MustDeclareVars', 1)

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

    _Main()

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

    Func _Main()
    Local $hGUI1, $hGUI2, $hHintergrund, $hGraphic1, $hGraphic2, $hSprite, $backbuffer, $bitmap

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

    ; Capture top left corner of the screen
    _ScreenCapture_Capture(@MyDocumentsDir & "\Hintergrund.jpg", 0, 0, 800, 600) ;hintergrund erstellen
    _ScreenCapture_Capture(@MyDocumentsDir & "\Sprite.jpg", 0, 0, 20, 20) ;Sprite erstellen
    ; Create a GUI for the original image
    $hGUI1 = GUICreate("Original", 800, 600, 0, 0)
    GUISetState()

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

    ; Initialize GDI+ library and load image
    _GDIPlus_Startup()
    $hHintergrund = _GDIPlus_ImageLoadFromFile(@MyDocumentsDir & "\Hintergrund.jpg") ;das ist der Hintergrund
    $hSprite = _GDIPlus_BitmapCreateFromFile(@MyDocumentsDir & "\Sprite.jpg") ;das ist das Sprite
    ; Draw original image
    $hGraphic1 = _GDIPlus_GraphicsCreateFromHWND($hGUI1) ;"Leinwand" erstellen auf der gemalt werden kann
    _GDIPlus_GraphicsDrawImage($hGraphic1, $hHintergrund, 0, 0) ;hintergrund auf diese Leinwand malen
    MsgBox(0, 0, "Hintergrund gezeichnet")

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

    _GDIPlus_GraphicsDrawImageRectRect($hGraphic1, $hSprite, 0, 0, 20, 20, 0, 0, 40, 40) ;das sprite wird doppelt so groß

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

    MsgBox(0, 0, "sprite gezeichnet, es folgt die Bewegung")

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

    For $i = 0 To 300 Step 2
    _GDIPlus_GraphicsDrawImageRectRect($hGraphic1, $hSprite, 0, 0, 20, 20, $i, $i, 40, 40)
    Next
    MsgBox(0, 0, "Das war gut, aber der Hintergrund wurde nicht aktualisiert, also nochmal....")

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

    For $i = 0 To 300 Step 2
    _GDIPlus_GraphicsDrawImage($hGraphic1, $hHintergrund, 0, 0) ;hintergrund auf diese Leinwand malen
    _GDIPlus_GraphicsDrawImageRectRect($hGraphic1, $hSprite, 0, 0, 20, 20, $i, $i, 40, 40)
    Next
    MsgBox(0, 0, "wars so gut? Nein, es flackert...wir benutzen einen sog. backbuffer, dabei wird das gesamte Bild im backbuffer erstellt und dieser danach erst komplett dargestellt")

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

    $bitmap = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphic1) ;Objekt erstellen
    $backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap) ;backbuffer erstellen, eine 2. Leinwand im Hintergrund sozusagen
    For $i = 0 To 300 Step 2
    _GDIPlus_GraphicsDrawImage($backbuffer, $hHintergrund, 0, 0) ;hintergrund in den backbuffer malen
    ; _GDIPlus_GraphicsDrawImage($backbuffer, $hsprite, $i, $i) ;Sprite in den backbuffer malen
    _GDIPlus_GraphicsDrawImageRectRect($backbuffer, $hSprite, 0, 0, 20, 20, $i, $i, 40, 40)
    _GDIPlus_GraphicsDrawImageRect($hGraphic1, $bitmap, 0, 0, 800, 600);gesamten backbuffer darstellen
    Next
    MsgBox(0, 0, "wars so gut? ja, so soll es sein ;-)")

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

    ; Release resources
    _GDIPlus_GraphicsDispose($hGraphic1)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_ImageDispose($hHintergrund)
    _GDIPlus_Shutdown()

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

    ; Clean up screen shot file
    FileDelete(@MyDocumentsDir & "\Hintergrund.jpg")
    FileDelete(@MyDocumentsDir & "\sprite.jpg")
    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

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

    EndFunc ;==>_Main

    [/autoit]

    /edit/ richtig schnell wird es, wenn so wenig Daten wie möglich bewegt werden müssen. Dazu wäre es sinnvoll, nicht den gesamten Hintergrund neu zu zeichnen, sondern nur das kleine Stück, welches vom "aktuellen" Sprite verdeckt wird

  • pdf silent print

    • Andy
    • 18. Dezember 2009 um 13:52

    Hi,
    ich verwende für silentdruck
    AcroRd32.exe /N /T PdfFile PrinterName [ PrinterDriver [ PrinterPort ] ]

  • Unterschiedliches Maximum von TCP

    • Andy
    • 18. Dezember 2009 um 13:11

    Hallo,
    google doch mal nach "MTU" oder schau bei wikipedia nach.
    Das Problem ist, die Länge der Pakete so groß einzustellen, daß möglichst wenig "overhead" entsteht und gleichzeitig im Fehlerfall (verlorenes Paket, miss) ein möglichst kleines Paket angefordert werden muß.

    Zitat

    Kann das unterschiedlich sein?

    Ja, das kann je nach Server/Client unterschiedlich sein.

    Zitat

    Und wenn ja wie kann man die Maximale länge rausfinden?

    s. MTU, ist dein Paket größer, dann wird es vor dem Versenden aufgeteilt, dann kann es sein, daß im Extremfall deine netto Datenubertragungsrate halbiert wird!
    Mit 1024 bist du aber idR auf der sicheren Seite.
    Schreib doch ein Script, welches die "optimale" Paketgröße bzgl. der Geschwindigkeit herausfindet!

  • Client zugriff + steuerung + File transfer

    • Andy
    • 17. Dezember 2009 um 16:15
    Zitat

    von jedem rechner aus über das Internet auf meinen Rechner zuhause zugreifen kann.

    Definiere "zugreifen".
    Um Dateien zu laden/speichern brauchst du lediglich einen FTP- oder HTTP-Fileserver, dann kannst du von jedem Browser aus dem Inet auf deinem Rechner Dateien laden/speichern.
    Ein HTTP-Server in einer einzigen Datei ist das kostenlose HFS. Zum Thema DYNDNS sag ich jetzt nichts, das ist selbstverständlich.

  • 1. C++ Gehversuche

    • Andy
    • 17. Dezember 2009 um 14:33
    Zitat

    Bist das wirklich du auf´m Foto?

    :rofl: , made my day!

  • Kommandozeilenbefehle mit Variablen

    • Andy
    • 17. Dezember 2009 um 13:28
    [autoit]

    ProcessSetPriority ()

    [/autoit]

    Ist ein weiterer Ansatz, Prioritäten mittels Script einfach zu verwalten?!

  • Monochromzeichnen eines Bildes

    • Andy
    • 17. Dezember 2009 um 12:02
    Zitat

    Ich dachte er daran, wie man in ASM programmiert, aber ich werde mal googeln!

    Ja, viel Spass dabei^^. Das ist jetzt Ernst gemeint, es gibt wunderschöne Seiten zu diesem Thema! Wenn du dich auf die Befehlssätze vom 8088 beschränkst, ist das für den Anfang absolut ausreichend, 80286 und 80386 erweitern die Befehle nur um 16- bzw 32 Bitbefehle.
    Als Referenz für die Befehle hab ich hier noch einen uralten Schinken in Papierform, allerdings ist u.a. HIER eine sehr gute Online-Referenz. Passend dazu das sehr treffend geschriebene TUTORIAL

    Für den, der eine in Assembler geschriebene dll zur Grafikbearbeitung und auch die passende AutoIt-Implementation sucht, ist HIER ein weiteres Highlight. UNBEDINGT die AutoIt Megademo ansehen!! Ist vergraben im Verzeichnis Demos und Scources (AutoIt) und dort im Verzeichnis Megademo. Eine der schönsten AutoIt-Demos, die ich bisher gesehen habe, der Code zeigt auch, wie einfach die Funktionen anzusprechen sind.

  • Vista 32bit -> Win7 64bit

    • Andy
    • 16. Dezember 2009 um 18:42
    Zitat

    den Pappi mal nen bischen aufrüsten .... so auf 100 GB

    30gig würden ja für den Anfang reichen, dann braucht auch keiner mehr diese lahmar***igen SSD-Krücken...gesamtes System und alle Anwendungen in den Speicher (Ramdisk) und 2x in der Stunde nen Speicherdump als Backup auf den Plattenstapel....*träum*

  • Random bmp Generator

    • Andy
    • 16. Dezember 2009 um 18:28

    Beweg die Maus dabei, und schon läufts schneller.....

  • Monochromzeichnen eines Bildes

    • Andy
    • 16. Dezember 2009 um 17:49

    Noch eine Anmerkung bzgl. Geschwindigkeit, die Lösung der ASM.au3 ist genauso schnell wie die "handcodierte". Irgend ein "Spezialist" hat die Ausführung der 3. Demo ausgestoppt und festgestellt, daß ein For $i=1 to 4: i+=1: next wesentlich schneller ist und darum sei die gesamte UDF langsam und somit Quatsch :cursing:
    Generell gibt es beim Aufruf von dll´s einen "overhead" an Befehlen um Variablen zu übergeben, Speicher anzufordern usw. Daß der overhead natürlich die Ausführung von den im Beispiel gebrachten 3-4 Prozessorbefehlen überwiegt, ist sonnenklar.
    Aber trancexx´ens Beispiel zeigt schonmal, wo geschwindigkeitsmäßig "der Hammer hängt" :rock:

  • Monochromzeichnen eines Bildes

    • Andy
    • 16. Dezember 2009 um 17:36

    es gibt 2 Möglichkeiten der Einbindung von Assemblercode:
    - trancexx (wie sollte es anders sein) hält es mit dem Motto der Frauen, je härter, je besser. Sie codet "zu Fuß", benutzt also keinen Assemblercode, sondern schreibt die Prozessorbefehle direkt per Bits und Bytes in den Speicher und setzt dann den Programmpointer auf diesen Code...crazy!

    Spoiler anzeigen
    [autoit]

    ; by trancexx
    #include <GUIConstantsEx.au3>
    #include <Memory.au3>

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

    Opt("GUIOnEventMode", 1)

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

    Global Const $STM_SETIMAGE = 370

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

    Global Const $iWidth = 800
    Global Const $iHeight = 470

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

    GUICreate("", $iWidth, $iHeight)
    GUISetOnEvent(-3, "_Quit")
    GUISetBkColor(0)

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

    Global $hPic = GUICtrlCreatePic("", 0, 0, $iWidth, $iHeight)

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

    Global $iSize = $iWidth * $iHeight
    Global $tBits = DllStructCreate("int[" & $iSize & "]")
    Global $pBits = DllStructGetPtr($tBits)

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

    Global $hBitmap, $aCall, $iHMsg
    Global $hPicHandle = GUICtrlGetHandle($hPic)

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

    Global $tRandom = DllStructCreate("dword")
    Global $pRandom = DllStructGetPtr($tRandom)

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

    GUISetState()

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

    Global $aRtlRandomEx = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("ntdll.dll"), "str", "RtlRandomEx")
    Global $pRtlRandomEx = $aRtlRandomEx[0]

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

    Global $aRtlMoveMemory = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("kernel32.dll"), "str", "RtlMoveMemory")
    Global $pRtlMoveMemory = $aRtlMoveMemory[0]

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

    Global $aSendMessageW = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("user32.dll"), "str", "SendMessageW")
    Global $pSendMessageW = $aSendMessageW[0]

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

    Global $aDeleteObject = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("gdi32.dll"), "str", "DeleteObject")
    Global $pDeleteObject = $aDeleteObject[0]

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

    Global $aCreateBitmap = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("gdi32.dll"), "str", "CreateBitmap")
    Global $pCreateBitmap = $aCreateBitmap[0]

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

    Global $pRemoteCode = _MemVirtualAlloc(0, 512, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)

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

    Local $tCodeBuffer = DllStructCreate("byte[512]", $pRemoteCode)

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

    #Region Assemply
    DllStructSetData($tCodeBuffer, 1, _
    "0x" & _
    "33DB" & _ ; xor ebx, ebx
    "68" & SwapEndian($pRandom) & _ ; push $pRandom
    "B8" & SwapEndian($pRtlRandomEx) & _ ; mov eax, RtlRandomEx
    "FFD0" & _ ; call eax
    "8BCB" & _ ; mov ecx, ebx
    "69C9" & SwapEndian(4) & _ ; imul ecx, 4
    "81C1" & SwapEndian($pBits) & _ ; add ecx, $pBits
    "68" & SwapEndian(3) & _ ; push 3 bytes
    "68" & SwapEndian($pRandom) & _ ; push $pRandom
    "51" & _ ; push ecx
    "B8" & SwapEndian($pRtlMoveMemory) & _ ; mov eax, RtlMoveMemory
    "FFD0" & _ ; call eax
    "43" & _ ; inc ebx
    "81FB" & SwapEndian($iSize) & _ ; cmp ebx, $iSize; <- compare ebx with $iSize
    "75" & Hex(256 - 53, 2) & _ ; jne -53 bytes; <- this is saying go back and do it again if not equal
    "68" & SwapEndian($pBits) & _ ; push $pBits
    "68" & SwapEndian(32) & _ ; push BitsPerPel
    "68" & SwapEndian(1) & _ ; push Planes
    "68" & SwapEndian($iHeight) & _ ; push $iHeight
    "68" & SwapEndian($iWidth) & _ ; push $iWidth
    "B8" & SwapEndian($pCreateBitmap) & _ ; mov eax, CreateBitmap
    "FFD0" & _ ; call eax
    "50" & _ ; push eax
    "68" & SwapEndian(0) & _ ; push IMAGE_BITMAP
    "68" & SwapEndian($STM_SETIMAGE) & _ ; push STM_SETIMAGE
    "68" & SwapEndian($hPicHandle) & _ ; push $hPicHandle
    "B8" & SwapEndian($pSendMessageW) & _ ; mov eax, SendMessageW
    "FFD0" & _ ; call eax
    "50" & _ ; push eax
    "B8" & SwapEndian($pDeleteObject) & _ ; mov eax, DeleteObject
    "FFD0" & _ ; call eax
    "C3" _ ; ret
    )
    #EndRegion Assembly

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

    ;While 1

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

    #region Assembly

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


    $t=timerinit()
    for $i=1 to 10
    DllCall("user32.dll", "int", "CallWindowProcW", _
    "ptr", $pRemoteCode, _
    "int", 0, _
    "int", 0, _
    "int", 0, _
    "int", 0)
    next
    #endregion Assembly
    $x=timerdiff($t)
    msgbox(0,0,$x)
    Sleep(10)
    while 1
    WEnd

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

    Func SwapEndian($iValue)
    Return Hex(Binary($iValue))
    EndFunc ;==>SwapEndian

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

    Func _Quit()
    Exit
    EndFunc ;==>_Quit

    [/autoit]

    - die zweite Möglichkeit ist "schön" :D
    Sprungmarken, eine "richtige" Assemblersyntax und andere feine Features sind in eine fertige Assembler-UDF eingebaut.

    Spoiler anzeigen
    [autoit]

    #include <ASM.au3>

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

    ; Initial an asm object
    Global $Asm = AsmInit()

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

    Demo1()
    Demo2()
    Demo3()
    Demo4()

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

    Func Demo1()
    ; Demo 1: Using Parameters
    AsmReset($Asm)
    AsmAdd($Asm, "push ebp")
    AsmAdd($Asm, "mov ebp, esp")
    AsmAdd($Asm, "mov eax, [ebp + 08]")
    AsmAdd($Asm, "add eax, [ebp + 0c]")
    AsmAdd($Asm, "pop ebp")
    AsmAdd($Asm, "retn 8")
    ConsoleWrite(String(AsmGetBinary($Asm)) & @CRLF)
    $Ret = MemoryFuncCall("int", AsmGetPtr($Asm), "int", 1, "int", 2)
    MsgBox(0, "Demo 1: Using Parameters", "1 + 2 = " & $Ret[0])
    EndFunc

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

    Func Demo2()
    ; Demo 2: Read Time-Stamp Counter
    AsmReset($Asm)
    AsmAdd($Asm, "push ebp")
    AsmAdd($Asm, "mov ebp, esp")
    AsmAdd($Asm, "rdtsc")
    AsmAdd($Asm, "mov ecx, [ebp + 08]")
    AsmAdd($Asm, "mov [ecx], edx")
    AsmAdd($Asm, "pop ebp")
    AsmAdd($Asm, "retn 4")
    ConsoleWrite(String(AsmGetBinary($Asm)) & @CRLF)
    $start=timerinit()
    $Ret = MemoryFuncCall("uint", AsmGetPtr($Asm), "uint*", 0)
    MsgBox(0, "Demo 2: Read Time-Stamp Counter",timerdiff($start)& " RDTSC = " & Hex($Ret[1]) & Hex($Ret[0], 8))
    Return Hex($Ret[1]) & Hex($Ret[0], 8)
    EndFunc

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

    Func Demo3()
    ; Demo 3: Using Label
    AsmReset($Asm)
    AsmAdd($Asm, "mov eax, 0")
    AsmAdd($Asm, "mov ecx, 10")
    AsmAdd($Asm, "label:")
    AsmAdd($Asm, "inc eax")
    AsmAdd($Asm, "loop @label")
    AsmAdd($Asm, "ret")
    ConsoleWrite(String(AsmGetBinary($Asm)) & @CRLF)
    $Ret = MemoryFuncCall("int", AsmGetPtr($Asm))
    MsgBox(0, "Demo 3: Using Label", "loop label for " & $Ret[0] & " times")
    EndFunc

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

    Func Demo4()
    ; Demo 4: Call AutoIt Func From Assembly
    $AutoItFunc = DllCallbackRegister("AutoItFunc", "int", "")
    AsmReset($Asm)
    AsmAdd($Asm, "call " & DllCallbackGetPtr($AutoItFunc))
    ;AsmAdd($Asm, "shl eax, 1")
    AsmAdd($Asm, "ret")
    ConsoleWrite(String(AsmGetBinary($Asm)) & @CRLF)
    $Ret = MemoryFuncCall("int", AsmGetPtr($Asm))
    MsgBox(0, "Demo 4: AutoIt Function", "BitShift return value of AutoItFunc: " & $Ret[0])
    DllCallbackFree($AutoItFunc)
    EndFunc

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

    Func AutoItFunc()
    MsgBox(0, "AutoItFunc", "Called by Inline Assembly")
    Return 1230
    EndFunc

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

    ; Release the asm object
    AsmExit($Asm)
    Exit

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


    Welche man letztendlich nutzt, bleibt jedem selbst überlassen, aber die ASM.au3 wäre mein Favorit.

  • Monochromzeichnen eines Bildes

    • Andy
    • 16. Dezember 2009 um 16:38
    Zitat

    Je nach Anwendung kann man sich ja den entstprechenden Code aussuchen!

    Allerdings, ich hatte den Wink schon richtig verstanden :D
    Das schöne an der Arbeit mit den structs ist, daß man die prospeed.dll ohne weiteres sofort einsetzen kann, das ist auch der einzige Grund, warum ich bisher den AutoIt-"Inlineassembler" nicht aktiviere. Gerade was den richtig schnellen Grafikkram betrifft, ist es besser, hier im Forum "den Ball ein wenig flach zu halten".
    Sonst werden die Jungs und Mädelz im "bösen" Forum wieder aufmerksam 8o, und ich bekomme wieder haufenweise PN´s nach Pixelsearch in "hiden fenstas" :rofl:

  • Monochromzeichnen eines Bildes

    • Andy
    • 16. Dezember 2009 um 04:43
    Zitat

    Ich war so frei und habe dein Beispiel gegen das GDI+ laufen lassen -> deins 3s. und GDI+ 45ms!

    Genau deshalb habe ich ja geschrieben, daß man die in GDI+ "eingebauten" Funktionen für diese speziellen Sachen verwenden soll, WENN sie schneller sind...
    Die von mir geposteten Beispiele zeigen einen direkten Weg zu den Bitmapdaten und haben mit GDI+ nichts zu tun. Obwohl ich mir ehrlich gesagt mit GDI+ einen abgebrochen habe, einzelne Pixel oder Bereiche aus Bildern auszulesen, was aber wahrscheinlich auch daran liegt, daß eine Datei zu öffnen, die Pixeldaten in ein Array einzulesen und weiterzuverarbeiten wesentlich einfacher und auch schneller ist.

    Wir nehmen das Graustufenbild der Mona Lisa und suchen alle Pixel mit einer bestimmten "Farbe" um damit z.B. ein bisschen Steganographie zu machen. Dann wäre es nützlich, einen 1:1 Bildvergleich zu machen und/oder die geänderten Pixel zu finden. Das könnte man mit GDI+ und ein bisschen cleverem Bitblt auch versuchen, allerdings bekommt man so weder Position noch Farbe der Pixel, sondern hat wieder ein weiteres "DifferenzBild".
    Wie bekommt man Informationen aus verrauschten Bildern einer Webcam? Wie lese ich den "Text" per OCR aus einem Bild? Alles Anwendungen, bei denen man direkt auf die Rohdaten zugreifen muß.... und einem GDI+ i.d.R. sehr wenig bringt...

    Zitat

    Schade nur, dass so stark auf das Thema Graustufen, und so wenig auf wirkliches Monochrom (Also wirklich nur Zweifarbig) eingegangen wurde.

    Na ändere doch im von UEZ geposteten Script einfach die Parameter. Schwarz/weiß ist doch nur die extremste Form der Graustufen.
    Oder füge in meinem Script (habe extra eine Leerzeile gelassen^^) in Zeile 27 ein:

    [autoit]

    if $grau<128 then
    $grau = 0
    Else
    $grau=255
    endif

    [/autoit]
  • Monochromzeichnen eines Bildes

    • Andy
    • 15. Dezember 2009 um 22:56

    Hi,
    ja, habe eine relativ schnelle Lösung(en) im engl. Forum gepostet, Zedna meinte sogar, ich solle meine Beispiele mal zusammenfassen und im dortigen Example-Forum publik machen....na schaumamal....

    Man muß die Dateien nicht unbedingt "sichtbar" machen, die Operationen direkt in der Bitmap sind wesentlich schneller und auch unkomplizierter (m.E.) als GDI+ (obschon man auch schon bei GDI+ auf "fertige" Funktionen zurückgreifen kann.
    Ich habe Dein "Bild nach Schwarzweiß" mal als Beispiel verwendet:
    Mona Lisa downloaden und im scriptverzeichnis speichern

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GDIPlusConstants.au3>
    #include <StructureConstants.au3>
    #include <WinAPI.au3>
    ; quick and dirty....
    Global $stride, $ptr, $pixeldata
    global $bitmapfile1, $width1, $height1, $stride1, $pbitmap1
    global $bitmapfile2, $width2, $height2, $stride2, $pbitmap2
    local $numberdiff = 0 ;number of differences between the 2 pics

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

    $pic1 = "mona-lisa.jpg" ;the image....24bit per pixel, could be a JPG which you want to have gray
    $pic3 = "grey.bmp" ;a bitmapfile with the greyscale

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

    $t=timerinit()
    _GDIPlus_Startup()
    $pixelstruct1 = getbmpdata($pic1, $width1, $height1, $stride1, $pbitmap1) ;get all data from file

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

    $lenght = DllStructGetSize($pixelstruct1) ;get lenght of bitmapdata
    $pixelstruct3 = dllstructcreate("ubyte["&$lenght&"]")
    ;compare
    for $i=1 to $lenght step 3
    $B=dllstructgetdata($pixelstruct1,1,$i) ;Farbanteil B
    $G=dllstructgetdata($pixelstruct1,1,$i+1) ;Farbanteil G
    $R=dllstructgetdata($pixelstruct1,1,$i+2) ;Farbanteil R
    $grau=int(($b+$g+$R)/3)

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

    dllstructsetdata($pixelstruct3,1,$grau,$i) ;write the difference into the difference-file, bottom-up isnt funny but we´ll mirror it later :o)
    dllstructsetdata($pixelstruct3,1,$grau,$i+1) ;write the difference into the difference-file, bottom-up isnt funny but we´ll mirror it later :o)
    dllstructsetdata($pixelstruct3,1,$grau,$i+2) ;write the difference into the difference-file, bottom-up isnt funny but we´ll mirror it later :o)
    next

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

    $head=DllStructcreate("ubyte[54]")
    ;lets create a bitmapfile with the given data
    $Bmpheader = DllStructCreate("align 1;char BM[2];uint Size;uint res;uint Offset;uint BMHI;uint Width;uint Height;short Planes;short BPP;uint BIcomp;int SizeImg;uint reshor;uint resver;uint col;uint colused", dllstructgetptr($head)) ;struct of bytes = header of bitmap #1
    ;fill struct(bitmapheader) with data
    DllStructSetData($bmpheader,"BM","BM")
    DllStructSetData($bmpheader,"Size",54+$lenght)
    DllStructSetData($bmpheader,"Offset",54)
    DllStructSetData($bmpheader,"BMHI",40)
    DllStructSetData($bmpheader,"Width",$width1)
    DllStructSetData($bmpheader,"Height",-$height1) ;negativ because "bottom up"
    DllStructSetData($bmpheader,"Planes",1)
    DllStructSetData($bmpheader,"BPP",24)
    DllStructSetData($bmpheader,"BIcomp",0)
    DllStructSetData($bmpheader,"SizeImg",$lenght)

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

    $header = dllstructgetdata($head,1) ;headerdata
    $pixeldata = stringtrimleft(DllStructGetData($pixelstruct3, 1),2) ;pixeldata
    $bitmap = $header&$pixeldata ;all together is the bitmap-file

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

    $filehandle = FileOpen($pic3, 18) ;write file
    FileWrite($filehandle,BinaryToString($bitmap))
    FileClose($filehandle)

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

    _GDIPlus_ImageDispose($pBitmap1) ;not in the function, because ImageDispose destroys the struct
    ;_GDIPlus_ImageDispose($pBitmap2)
    $m=timerdiff($t)/1000

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

    ;lets have a look what we have done...
    GUICreate("Pic2Gray "&$width1&"x"&$height1&" = "&$width1*$Height1&" Pixel in "&int($m)&" Seconds => "&int($width1*$Height1/$m)&" Pixel/Second",800,500)
    GUICtrlCreatePic($pic1, 10, 10, 350, 350 / $width1 * $height1)
    GUICtrlCreatePic($pic3, 400, 10, 350, 350 / $width1* $height1)
    GUISetState()

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

    Do
    Until GUIGetMsg() = -3

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

    Func getbmpdata($bmpfile, ByRef $width, ByRef $height, ByRef $stride, Byref $pbitmap) ;returns a struct with the data of the pixel
    $pbitmap = _GDIPlus_BitmapCreateFromFile($bmpfile)
    ;_GDIPlus_BitmapLockBits gibt $tagGDIPBITMAPDATA-Struktur zurück
    $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF24RGB)
    If @error Then MsgBox(0, "", "Error locking region " & @error)
    $stride = DllStructGetData($BitmapData, "Stride");Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up.
    $width = DllStructGetData($BitmapData, "Width");Image width - Number of pixels in one scan line of the bitmap.
    $height = DllStructGetData($BitmapData, "Height");Image height - Number of scan lines in the bitmap.
    ;$pixelFormat = DllStructGetData($BitmapData, "PixelFormat");Pixel format - Integer that specifies the pixel format of the bitmap
    $Scan0 = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap.
    $pixeldata = DllStructCreate("ubyte[" & (Abs($stride) * ($height)) & "]", $Scan0)
    $BMPData = DllStructGetData($pixeldata, 1)
    _WinAPI_DeleteObject($pbitmap)
    _GDIPlus_BitmapUnlockBits($pBitmap, $BmpData)
    ;_GDIPlus_ImageDispose($pBitmap) ;destroys the pixeldatastruct, have to be done at end of the script!
    return $pixeldata
    EndFunc ;==>getbmpdata

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

    Das von UEZ gepostete Beispiel benutzt z.B. eins dieser in GDI+ "eingebauten" Features, in diesem Fall die Beeinflussung der Farben. Um aber in eine(r) Datei zu "malen" bzw einzelne Bytes zu lesen/beeinflussen muß man schauen, welche Funktion am besten "hinhaut".

  • PixelGetColor von einem Bild

    • Andy
    • 15. Dezember 2009 um 21:39
    Zitat

    Die Farbe eines Pixels kannst du nur abfragen, wenn das Bild auch offen ist

    Ich weiß worauf du hinaus willst ;) , aber das war keine Frage nach einem Pixel in einem "versteckten oder hidden" Fenster.
    Selbstverständlich kann man alle Pixel aus einer Bilddatei lesen und auch schreiben...

  • PixelGetColor von einem Bild

    • Andy
    • 15. Dezember 2009 um 21:32

    Also sehr einfach geht es so....

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <GDIPlusConstants.au3>
    #include <WinAPI.au3>
    #include <GDIPlus.au3>
    ;"\pic2.jpg"
    ;"\testfullscreen.bmp"
    $t = TimerInit()
    $color=_GetPixelFromBMP("pic2.jpg",100,100) ;Rückgabe: Farbe in BGR Input: file, umd die Koordinaten x und y
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $color = ' & $color & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $m = TimerDiff($t)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : time = ' & $m & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

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

    Func _GetPixelFromBMP($sImage,$x,$y )
    Local $pbitmap, $Bmp
    Local $tBD, $iWidth, $iHeight, $iStride
    Local $pData, $color

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

    _GDIPlus_Startup()
    $pbitmap = _GDIPlus_ImageLoadFromFile($sImage) ;bild laden
    If @error Then Return SetError(1, 2, 0)
    $tBD = _GDIPlus_BitmapLockBits($pbitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF24RGB)
    If @error Then MsgBox(0, "", "Error locking region " & @error)
    $iWidth = DllStructGetData($tBD, 1) ;breite der bitmap
    $iHeight = DllStructGetData($tBD, 2) ;hoehe der bitmap
    $iStride = DllStructGetData($tBD, 3) ;Erklärung : http://www.autoitscript.com/forum/index.ph…ndpost&p=753169
    $pData = DllStructGetData($tBD, 5) ;pointer auf die bitmapdaten
    $Bmp = DllStructCreate("byte[" & $iStride * $iHeight & "]", $pData) ;struct gefüllt mit den Daten der Bitmap

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

    $position = $istride * ($y - 1) + 3 * ($x-1) ;Umrechnung der Position von x- und y- Koordinaten
    $substruct = DllStructCreate("ubyte[3]", DllStructGetPtr($Bmp) + $position) ;eine 3-byte struct an die position vom pixel schreiben
    $Color = DllStructgetData($substruct, 1) ;Daten aus der struct lesen

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

    _GDIPlus_BitmapUnlockBits($pbitmap, $tBD)
    ;_WinAPI_DeleteObject($hBmp)
    _GDIPlus_ImageDispose($pbitmap)
    _GDIPlus_Shutdown()
    return $color
    EndFunc ;==>_GetImagePixels

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

    für weiter Fragen nach dem Erstellen/Bearbeiten einer Bitmap verweise ich auf die Threads HIER und insbesondere HIER

  • Dummy-Editor in Autoit ?

    • Andy
    • 15. Dezember 2009 um 19:19
    Zitat

    da ich einfach nur einen Editor brauche, welcher erweiterbar ist....

    da stellt sich mir die Frage, wieso du nicht einen der schon fertigen, erweiterbaren Editoren benutzt, wie z.B.

    UltraEdit (50€ aber jeden Cent wert)
    TextPad (~20€)

    Kostenlose Editoren:
    Notepad++
    PSPad
    ConText
    jEdit
    TextWrangler

    Komodo Edit 4.0
    Williams
    Texteditor, der mehrere Programmier- und Auszeichnungssprachen wie Perl, PHP, Python, Ruby und Tcl, CSS, HTML und XML beherrscht; mit Syntaxhervorhebung, Auto-Vervollständigung und einem Projektmanager; über eigene XPI-Extension erweiterbar

    Weaverslave 3.9.18
    Thomas Weinert
    Editor für verschiedene Skript- und Auszeichnungssprachen mit Syntax-Hervorhebung und Tag-Vervollständigung; erweiterbar über ein Activescript-Interface sowie Programmbibliotheken


    In der C´t 23/2009 wurden einige Editoren getestet, den Artikel gibts HIER

  • Wieso ist eine Struct größer als ihre definitierte Größe?

    • Andy
    • 15. Dezember 2009 um 13:42
    Zitat

    Sobald man mehr als ein Minimum an Speicher hat, lohnt sich das sicherlich

    touché :thumbup:

  • Wieso ist eine Struct größer als ihre definitierte Größe?

    • Andy
    • 15. Dezember 2009 um 12:38
    Zitat

    Autsch
    da haben wir diesmal auch vergessen die Hilfe zu lesen.

    uuuuuuhhhhh....schande, am schlimmsten daran ist, daß ich mir letzte Woche noch beim durchsehen alter Assemblerprogramme Infos bzgl. des Alignments geholt habe...

    Zitat

    Man merkt, das BugFix noch an C64 Zeiten sich gerne zurückerinnert. 64 Kilobyte Ram. Wow, war das viel

    Es geht nicht primär um den Speicherverbrauch, sondern darum, daß man mit der "Überlagerung" mehrerer Structs in einem Speicherbereich sehr schnell und einfach (für AutoItverhältnisse) Daten ändern/bearbeiten kann.

    Zitat

    Suchen sich das größte Struckt raus und multiplizieren es mit der Anzahl der Structs. (So geht man auf Nummer sicher.)

    Verstehe ich ehrlich gesagt nur vor dem Hintergrund, daß man so keine Verweise auf die Größe der einzelnen Elemente zwischenspeichern muss. Somit haben die Pointer auf die einzelnen Elemente immer denselben Abstand => schnelleres "durchlaufen" bei großen Structs (Arrays), und das Schreiben von Daten in Prozessor-Register funktioniert ohne vorheriges "anpassen" (alignment).

  • Wieso ist eine Struct größer als ihre definitierte Größe?

    • Andy
    • 14. Dezember 2009 um 21:49

    Hallo zusammen,
    beim Arbeiten mit structs ist mir etwas aufgefallen, was ich so nicht erwartet hätte:
    Wenn man eine Struct mit

    [autoit]

    $struct1=dllstructcreate(byte[8])

    [/autoit]

    erstellt, dann hat diese Struct eine Größe von 8 Byte, soweit klar!
    Aber!
    Erstellt man nun eine struct, welche genau "über" der andern struct liegt (bzw an deren Position im Speicher) dann sieht man, daß die Elemente in einer Struct immer so groß sind (Bitanzahl) wie das größte Einzelelement.
    Bsp:

    [autoit]

    $struct1=dllstructcreate("byte[12]") ;12 Byte
    $struct2=DllStructCreate("byte;int;byte",dllstructgetptr($struct1)) ;6 Byte an der Position von struct1

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

    ;schreiben in die struct2, real geschrieben wird an position der struct1
    dllstructsetdata($struct2,1,0xAB) ;1 Byte
    dllstructsetdata($struct2,2,0xAABBCCDD) ;4 Byte
    dllstructsetdata($struct2,3,0xBA) ;1 Byte

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

    ;nun sollte man erwarten, daß (little endian) der Inhalt der struct1 "ABDDCCBBAABA" ist...byte&int&byte=6 byte

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

    ;lesen der Daten von struct1
    $wert=dllstructgetdata($struct1,1) ;12 byte werden gelesen, aber der Inhalt ist AB000000DDCCBBAABA000000 also nicht ABDDCCBBAABA
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $wert = ' & $wert & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

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

    ;sieht man auch an den pointern
    $p1=dllstructgetptr($struct2,1)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $p1 = ' & $p1 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $p2=dllstructgetptr($struct2,2)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $p2 = ' & $p2 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $p3=dllstructgetptr($struct2,3)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $p3 = ' & $p3 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    ;der abstand der pointer beträgt 4 byte

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

    das heißt, daß obwohl bei der Definition der struct2 für das erste Element als Größe 1 Byte angegeben wird, ist der tatsächliche "Speicherverbrauch" 4 Byte. Wieso das?
    Bei einer struct von "byte;int64;byte" ist die tatsächliche Größe nicht 1+8+1 bytes sondern 3*8 Bytes, gibts dafür einen Grund?

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™