Optische Täuschung - Animation

  • Hi,
    nach langer konnte ich mich mal wieder hinreißen und habe etwas in AutoIt gemacht. Es handelt sich um eine optische Täuschung, bei der Streifen über ein bestimmtes Bild gezogen werden, um eine Animation zu erzeugen.
    Da ich sehr fasziniert von diesem Video bin, versuchte ich mich an einer Implementation und siehe da: Es funktioniert. Wenn man sich etwas mehr mit dem Thema beschäftigen würde, könnte da bestimmt ein kleines Mini Game (oder etwas in der Richtung) draus werden.

    Wenn ihr die Motive wechseln wollt dann kommentiert einfach die verschiedenen $sPicture Variablen ein und aus. Die benutzten Bilder stammen nicht von mir und sind unter dem o.g. Video verlinkt.
    Das Script kann man mit einem Tastendruck auf Escape beenden.

    Code
    [autoit]

    #include <gdiplus.au3>
    #include <winapi.au3>
    #include <windowsconstants.au3>

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

    ; ### Bildpfad anpassen!
    Global $sPicture = @ScriptDir & "\0.jpg"
    ;~ Global $sPicture = @ScriptDir & "\1.jpg"
    ;~ Global $sPicture = @ScriptDir & "\2.jpg"
    ;~ Global $sPicture = @ScriptDir & "\3.jpg"
    ;~ Global $sPicture = @ScriptDir & "\4.jpg"
    ;~ Global $sPicture = @ScriptDir & "\5.jpg"
    ; ###

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

    Global $iWidth = 1024
    Global $iHeight = 768
    Local $iFPSRate = 100
    Local $iOffsetRate = 2 ;1,2 oder 4

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

    HotKeySet("{ESC}", "_Exit")
    $hGUI = GUICreate("Optische Täuschung - Animation", $iWidth, $iHeight)
    GUISetState()

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

    ;Create Backbuffer
    $hGUIDC = _WinAPI_GetDC($hGUI)
    $hBackbufferBitmap = _WinAPI_CreateCompatibleBitmap($hGUIDC, $iWidth, $iHeight);
    $hBackbufferDC = _WinAPI_CreateCompatibleDC($hGUIDC);
    _WinAPI_SelectObject($hBackbufferDC, $hBackbufferBitmap)

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

    ;Gdi+ Startup
    _GDIPlus_Startup()
    $hBackbufferGraphics = _GDIPlus_GraphicsCreateFromHDC($hBackbufferDC)

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

    ;Load background
    $hImgBitmap = _WinAPI_CreateCompatibleBitmap($hGUIDC, $iWidth, $iHeight);
    $hImgDC = _WinAPI_CreateCompatibleDC($hGUIDC);
    _WinAPI_SelectObject($hImgDC, $hImgBitmap)
    $hImageGraphics = _GDIPlus_GraphicsCreateFromHDC($hImgDC)
    $hImage = _GDIPlus_ImageLoadFromFile($sPicture)
    _GDIPlus_GraphicsDrawImageRect($hImageGraphics, $hImage, 0, 0, $iWidth, $iHeight)

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

    Local $iOffset = 0
    Local $iTimePerFrame = (1/$iFPSRate) * 1000
    local $hNTDLL = DllOpen("ntdll.dll")
    Local $tTime = DllStructCreate("int64 time;")

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

    While Sleep(15)
    $hTimer = TimerInit()

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

    _WinAPI_BitBlt($hBackbufferDC, 0, 0, $iWidth, $iHeight, $hImgDC, 0, 0, $SRCCOPY) ;Background
    _GDIPlus_GraphicsFillRect($hBackbufferGraphics, 0, 0, $iOffset - 2, $iHeight) ; First stripe

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

    ;other stripes
    For $x = 0 To $iWidth - 1 Step 2
    _GDIPlus_GraphicsFillRect($hBackbufferGraphics, $x + $iOffset, 0, 16, $iHeight)
    $x += 16
    Next
    $iOffset += $iOffsetRate
    If $iOffset >= 16 Then $iOffset = 0

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

    _WinAPI_BitBlt($hGUIDC, 0, 0, $iWidth, $iHeight, $hBackbufferDC, 0, 0, $SRCCOPY) ; Back -> Frontbuffer

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

    ;frame control
    $iTime = TimerDiff($hTimer)
    if $iTime < $iTimePerFrame Then _HighPrecisionSleep(($iTimePerFrame-$iTime)*1000)
    WEnd

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

    Func _Exit()
    _WinAPI_DeleteDC($hImgDC)
    _WinAPI_DeleteObject($hImgBitmap)
    _GDIPlus_GraphicsDispose($hImageGraphics)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_GraphicsDispose($hBackbufferGraphics)
    _WinAPI_DeleteDC($hBackbufferDC)
    _WinAPI_DeleteObject($hBackbufferBitmap)
    _WinAPI_DeleteDC($hGUIDC)
    _GDIPlus_Shutdown();
    DllClose($hNTDLL)
    Exit
    EndFunc ;==>_Exit

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

    ; Author ........: Andreas Karlsson (monoceres)
    ; Modified.......: Sprenger120
    Func _HighPrecisionSleep($iMicroSeconds,$hDll=False)
    DllStructSetData($tTime,"time",-1*($iMicroSeconds*10))
    DllCall($hNTDLL,"dword","ZwDelayExecution","int",0,"ptr",DllStructGetPtr($tTime))
    EndFunc

    [/autoit]
  • du 9gagger xD
    naja echt nice Täuschung^^
    und hast gut in Autoit "nachgebaut"

    Sind TV-Quizfragen zu einfach? A) Ja B) Harry Potter

    Spoiler anzeigen

    Ich gebe zu dieser Post hat wahrscheinlich nicht viel geholfen,
    aber ich versuche wenigstens zu helfen :rolleyes:

  • Hi,

    Zitat

    Witzig wärs Bilder selbst zu erstellen die durch diesen effect betroffen sind.

    naja, mit bissl nachdenken wie diese "optische Täuschung" überhaupt funktioniert ist ein Erstellen von Bildern kein Problem.
    Genau so funktioniert nämlich ein "Daumenkino" 8)

  • Wer schreibt ein Script, dass ein "Daumenkino" auf einer Seite darstellt mit der dazugehörenden Streifenfolie zum ausdrucken?

  • Wer schreibt ein Script, dass ein "Daumenkino" auf einer Seite darstellt mit der dazugehörenden Streifenfolie zum ausdrucken?

    Ich wollte das Script mit dem Satz in keiner Weise kritisieren, mir ist klar, dass das Script so wie es ist sinnvoll ist. Der Satz war mehr eine Feststellung, sonst nichts. Die bewegten Figuen im Video haben mich einfach mehr beeindruckt als die auf dem Bildschirm. Trotzdem finde ich das Script toll und interessant.

  • Schöner Effekt, den du da erzeugst.
    Andy: Das ist eher das gleiche Prinzip wie bei Wackelbildern, nur statt den Linsen wird die Streifenfolie bewegt. Beim Daumenkino wird das Bild nicht aus einzelnen Streifen zusammengesetzt, sondern ist immer komplett vorhanden. Ganz klar ist das selbstgemachte Papierbild viel beeindruckender als das ganze digital (auf dem PC-Bildschirm lässt sich so vieles darstellen) oder die Fertigware (viel zu oft gesehen)

  • Coole Sache :)
    Fehlt nur noch die Funktion selbst Bilder um zu wandeln und samt Folie aus zu drucken.
    (Folie muss halt noch ausgeschnitten werden ^^)

  • Sieht wirklich cool aus! Ich versuch mich mal an dem "Bild ersteller". Man wird wohl 2 oder mehr Gleichgroße Bilder brauchen (Schwarz-Weiß natürlich) und dann werden von den Bildern bestimmte Teile weggeschnitten und dann zusammengesetzt. Mal schaun.

    EDIT: Ums mir ein wenig zu veranschaulichen hab ich mir auch schnell mal so ein Folien-Drüberzieh Script geschrieben, wens interessiert:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GDIP.au3>

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

    Opt("GUIOnEventMode", 1)

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

    _GDIPlus_Startup()
    Global $Balken_Size = 10, $Hole_Size = 2, $_x = -($Balken_Size + $Hole_Size)
    Global $sPath = @ScriptDir & "\1.jpg"
    Global $hImage = _GDIPlus_BitmapCreateFromFile($sPath)
    Global $nWidth = _GDIPlus_ImageGetWidth($hImage) / 5, $nHeight = _GDIPlus_ImageGetHeight($hImage) / 5

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

    $hWnd = GUICreate("Test", $nWidth, $nHeight)
    GUISetOnEvent(-3, "_Exit", $hWnd)
    GUISetState()

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

    $hDC = _WinAPI_GetDC($hWnd)
    $hDC_Buffer = _WinAPI_CreateCompatibleDC($hDC)
    $hGDI_Bitmap = _WinAPI_CreateCompatibleBitmap($hDC, $nWidth, $nHeight)
    _WinAPI_SelectObject($hDC_Buffer, $hGDI_Bitmap)
    $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_Buffer)

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

    $Raster = _GDIPlus_BitmapCreateFromScan0($nWidth+($Balken_Size + $Hole_Size), $nHeight)
    $Temp_Graphic = _GDIPlus_ImageGetGraphicsContext($Raster)
    For $i = 0 To (($nWidth) / ($Balken_Size + $Hole_Size)) +1
    _GDIPlus_GraphicsFillRect($Temp_Graphic, $i * ($Balken_Size + $Hole_Size), 0, $Balken_Size, $nHeight)
    Next
    _GDIPlus_GraphicsDispose($Temp_Graphic)

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

    ;; background laden
    $hImage_BG = _GDIPlus_ImageLoadFromFile($sPath)
    ;; background auf DC kopieren
    $hDC_Buffer_BG = _WinAPI_CreateCompatibleDC($hDC)
    $hGDI_Bitmap_BG = _WinAPI_CreateCompatibleBitmap($hDC, $nWidth, $nHeight)
    _WinAPI_SelectObject($hDC_Buffer_BG, $hGDI_Bitmap_BG)

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

    $hGraphics_BG = _GDIPlus_GraphicsCreateFromHDC($hDC_Buffer_BG)
    _GDIPlus_GraphicsDrawImageRect($hGraphics_BG, $hImage_BG, 0, 0, $nWidth, $nHeight)
    _GDIPlus_GraphicsDispose($hGraphics_BG)

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

    While Sleep(20)
    _WinAPI_BitBlt($hDC_Buffer, 0, 0, $nWidth, $nHeight, $hDC_Buffer_BG, 0, 0, 0x00CC0020)
    ;; RASTER
    $_x -= 1
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $Raster, $_x, 0, $nWidth+($Balken_Size + $Hole_Size), $nHeight)
    If $_x <= -($Balken_Size + $Hole_Size) Then $_x = 0
    _WinAPI_BitBlt($hDC, 0, 0, $nWidth, $nHeight, $hDC_Buffer, 0, 0, 0x00CC0020)
    WEnd

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

    Func _Exit()
    _WinAPI_DeleteDC($hDC)
    _GDIPlus_BitmapDispose ($Raster)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    mfg BB

    "IF YOU'RE GOING TO KILL IT
    OPEN SOURCE IT!"

    by Phillip Torrone

    Zitat von Shoutbox

    [Heute, 11:16] Andy: ....böseböseböseböse....da erinnere ich mich daran, dass man den Puschelschwanz eines KaRnickels auch "Blume" nennt....ob da eins zum anderen passt? :rofl: :rofl: :rofl: :rofl:

    https://autoit.de/index.php?page…leIt#post251138

    Neon Snake

  • @progandy,
    beim Daumenkino entsteht die "Bewegung" dadurch, dass einzelne Bilder nacheinander dargestellt werden. Genau so funktioniert ja das "Streifenfolienkino" auch, nur dass ALLE Seiten gleichzeitig auf einem Blatt Papier dargestellt sind. Die Streifen in der Folie verdecken nur immer die restlichen Bilder und zeigen nur eine einzelne "Seite" des Daumenkinos.
    Also gewissermassen 3D-Daumenkino auf 2D komprimiert :rofl:

    Das bringt mich auf eine Idee.
    Man könnte das Bild auf eine Walze aufziehen und diese (endlos) vor einer fix stehenden Lochmaske bewegen...
    Irgendwer hat so ein Ding bestimmt schon vor 100 Jahren gebaut....

  • Das bringt mich auf eine Idee.

    Man könnte das Bild auf eine Walze aufziehen und diese (endlos) vor einer fix stehenden Lochmaske bewegen...

    Irgendwer hat so ein Ding bestimmt schon vor 100 Jahren gebaut....

    Jap, das gibts schon und steht so ähnlich in jedem zweiten Technikmuseum. Nur etwas kompakter: Wenn ich es richtig in Erinerung habe, sehen die Teile da so aus (ja ok, meine Malkünste sind beschränkt :rolleyes: :(
    [Blockierte Grafik: http://s14.directupload.net/images/120911/ehkvwpqi.png]

    Die Bilder sind in regelmäsigen Abständen auf der Innenseite der Walze angebracht. Zwischen den Bildern ist Platz zum Durchschauen. Man setzt sich also vor die Walze und schaut durch einen der Schlitze in das Innere der Walze auf ein Bild. Dann beginnt man die Walze zu drehen und man hat sieht das bewegte Bild.

  • So, hab ein kleines Script geschrieben was mehrere Bilder zu einem Bild zusammenfügt.
    Müssen nur alle gleich groß sein. Dann die Anzahl, die größe der Lücke zwischen den Bildern, die Größe und die Namen der Bilder und schon hat man ein Bild ;)

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GDIP.au3>

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

    Opt("GUIOnEventMode", 1)

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

    _GDIPlus_Startup()
    Global $Balken_Size = 10, $Hole_Size = 2, $_x = -($Balken_Size + $Hole_Size)
    Global $sPath = @ScriptDir & "\BILD1.png"
    Global $hImage = _GDIPlus_BitmapCreateFromFile($sPath)
    Global $nWidth = _GDIPlus_ImageGetWidth($hImage), $nHeight = _GDIPlus_ImageGetHeight($hImage)

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

    $hWnd = GUICreate("Test", $nWidth, $nHeight)
    GUISetOnEvent(-3, "_Exit", $hWnd)
    GUISetState()

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

    $hDC = _WinAPI_GetDC($hWnd)
    $hDC_Buffer = _WinAPI_CreateCompatibleDC($hDC)
    $hGDI_Bitmap = _WinAPI_CreateCompatibleBitmap($hDC, $nWidth, $nHeight)
    _WinAPI_SelectObject($hDC_Buffer, $hGDI_Bitmap)
    $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_Buffer)

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

    $Raster = _GDIPlus_BitmapCreateFromScan0($nWidth + ($Balken_Size + $Hole_Size), $nHeight)
    $Temp_Graphic = _GDIPlus_ImageGetGraphicsContext($Raster)
    For $i = 0 To (($nWidth) / ($Balken_Size + $Hole_Size)) + 1
    _GDIPlus_GraphicsFillRect($Temp_Graphic, $i * ($Balken_Size + $Hole_Size), 0, $Balken_Size, $nHeight)
    Next
    _GDIPlus_GraphicsDispose($Temp_Graphic)

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

    $BG=_BearbeiteBilder(6, $Hole_Size, 500, 500, "BILD1.png", "BILD2.png", "BILD3.png", "BILD4.png", "BILD5.png", "BILD6.png")
    _GDIPlus_ImageSaveToFile ($BG, "Ball.jpg")
    ;; background laden
    $hImage_BG = _GDIPlus_ImageLoadFromFile($sPath)
    ;; background auf DC kopieren
    $hDC_Buffer_BG = _WinAPI_CreateCompatibleDC($hDC)
    $hGDI_Bitmap_BG = _WinAPI_CreateCompatibleBitmap($hDC, $nWidth, $nHeight)
    _WinAPI_SelectObject($hDC_Buffer_BG, $hGDI_Bitmap_BG)

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

    $hGraphics_BG = _GDIPlus_GraphicsCreateFromHDC($hDC_Buffer_BG)
    _GDIPlus_GraphicsDrawImageRect($hGraphics_BG, $hImage_BG, 0, 0, $nWidth, $nHeight)
    _GDIPlus_GraphicsDispose($hGraphics_BG)

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

    While Sleep(100)
    _GDIPlus_GraphicsClear ($hGraphics, 0xFF00FF00)
    _GDIPlus_GraphicsDrawImageRect ($hGraphics, $BG, 0, 0, $nWidth, $nHeight)
    ;~ _WinAPI_BitBlt($hDC_Buffer, 0, 0, $nWidth, $nHeight, $hDC_Buffer_BG, 0, 0, 0x00CC0020)
    ;; RASTER
    $_x -= 1
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $Raster, $_x, 0, $nWidth+($Balken_Size + $Hole_Size), $nHeight)
    If $_x <= -($Balken_Size + $Hole_Size) Then $_x = 0
    _WinAPI_BitBlt($hDC, 0, 0, $nWidth, $nHeight, $hDC_Buffer, 0, 0, 0x00CC0020)
    WEnd

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

    Func _BearbeiteBilder($nCount, $break, $width, $height, $sImage1, $sImage2, $sImage3 = 0, $sImage4 = 0, $sImage5 = 0, $sImage6 = 0)
    $all = _GDIPlus_BitmapCreateFromScan0($width, $height)
    $graphic = _GDIPlus_ImageGetGraphicsContext($all)
    For $i = 0 To $nCount - 1
    $temp = Eval("sImage" & $i+1)
    $img_btm = _GDIPlus_BitmapCreateFromFile($temp)

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

    For $j = 0 To ($width / $break) / $nCount
    _GDIPlus_GraphicsDrawImageRectRect($graphic, $img_btm, $i * $break + ($j * ($break * $nCount)), 0, $break, $height,$i*$break +( $j * ($break*$nCount)), 0, $break, $height)
    Next

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

    ;~ _GDIPlus_BitmapDispose($img_btm)
    Next

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

    _GDIPlus_GraphicsDispose($graphic)

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

    Return $all
    EndFunc ;==>_BearbeiteBilder

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

    Func _Exit()
    _WinAPI_DeleteDC($hDC)
    _GDIPlus_BitmapDispose($Raster)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    Bild eines Balls der von oben nach unten hüpft:
    http://www.mediafire.com/view/?xorq7583a71up4q

    Ringe die entstehen:
    http://www.mediafire.com/view/?od4bl5vv5xzh3bx

    mfg BB

    "IF YOU'RE GOING TO KILL IT
    OPEN SOURCE IT!"

    by Phillip Torrone

    Zitat von Shoutbox

    [Heute, 11:16] Andy: ....böseböseböseböse....da erinnere ich mich daran, dass man den Puschelschwanz eines KaRnickels auch "Blume" nennt....ob da eins zum anderen passt? :rofl: :rofl: :rofl: :rofl:

    https://autoit.de/index.php?page…leIt#post251138

    Neon Snake

    Einmal editiert, zuletzt von BadBunny (11. September 2012 um 18:33)