Pixiv Ugoira zip anime player basicly done. Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
brutus_skywalker
Posts: 175
Joined: 24 Dec 2016, 13:16
Location: Antarctica

Re: Pixiv Ugoira zip anime player basicly done.

19 Feb 2017, 21:46

" Not very useful script , but if your like the
Hulagirl.ahk , can think this is an update . "

Hence my elation...

awesome.
Outsourcing Clicks & Presses Since 2004.
tallguyyo
Posts: 2
Joined: 07 Dec 2019, 18:51

Re: Pixiv Ugoira zip anime player basicly done.

07 Dec 2019, 20:47

im sorry, I am newbie when comes to scripting and using it. where can I go about to attain a copy of this tool to play animation directly from zip file?

i understand it is a script .ahk i need to run using autohotkeys but where can I get the .ahk?
tallguyyo
Posts: 2
Joined: 07 Dec 2019, 18:51

Re: Pixiv Ugoira zip anime player basicly done.

24 Dec 2019, 17:59

brutus_skywalker wrote:
10 Feb 2017, 02:57
"And the uncompressed zippack frames player is basically done."
"it's freaking done!" :bravo:
FREAKIN AWESOME, i FOOLISHLY had doubts, i can think of a few applications for this,hell one can easily combine this with http://www.autohotkey.com/board/topic/87068-binrun-run-binary-executable-from-memory-eg-resource/?hl=binrun, since one can load the zip file in a compiled script to memory,now you can actually have animated splash images and such with out every extracting a single MEG of data from a compiled exe. I must also say i learned a few new tricks from your code,for my future endeavors, so Thanks. I rarely stray into GUI's and out side of logic & math driven console-code mainly in python,now i can roam a bit farther....

A frames per second control variable will also be usefull for your final version,i had to add a few sleep commands to throttle cpu usage.

AWESOMEjob dude.
peter723pan wrote:
09 Feb 2017, 10:40
brutus_skywalker wrote:Brilliant,thanks for the quick heads up,best of luck with the zipped playback.
I add a memory free line . After the File.close()

Code: Select all

        File.Close()
        VarSetCapacity(Buffer, 0) 
And the uncompressed zippack frames player is basicly done.

https marcan.st /talks/2014_pixiv_ugoku_player/ Broken Link for safety
Download this pixiv Ugoira player demo page zip pack test.
https marcan.st /talks/2014_pixiv_ugoku_player/ Broken Link for safetyimg/cirno.zip
or a small one, change script to read it :
https marcan.st /talks/2014_pixiv_ugoku_player/ Broken Link for safetyimg/katakata.zip

Still need add get the filename of script itself , fullscreen , resize , combine Gdip.ahk lines in script and remove unused Gdip.ahk lines.
Just finished main function.

Edit post Update:

Combining Gdip.ahk that part I keep it myself. Since play Ugoria zip pack just my personal interest, read Ugoria frame delay list is not content in this post.
Just consider it is an update for hulagirl.ahk

All other coding finished.

Still can only read "store" type zip pack, add support for none Ugoria zip pack ,which winrar 7zip created "store-noncompressed" zip file.
Now can skip file extra info data , skip folders in zip.

Compressed type not support , can't find good AHK example for doing that , and some of it need extra .dll , which I don't want to.
GDI+ drawing still not very fast while resizing picture, but DirectDraw , I search those old threads on forum , nobody can do it .


How to use it . For example Hulagirl , pack png files of Hulagirl in a zip pack , compress type choose "store".
Now your get a Hulagirl.zip
Rename this script to Hulagirl.ahk , it will read the zip pack with the same main filename (in same folder), just like subtitle file.

Right Mouse Button Toggle Pause : while in pause , mouse wheel down , pageDown key , Xbutton2 make show next frame ,
mouse wheel up , pageUp key , Xbutton1 make show previous frame ,

Middle Mouse Button Toggle Fullscreen , it's auto fit.

Left Mouse Button drag window.

ESC key exit script.

Keeping Right Mouse Button down then click Left Mouse Button also exit script.

Sorry for my bad English discrption , I know my words had some grammar mistakes.
It have been long time since left school, English is not my native lauguage. 我说中文。

Code: Select all


#include Gdip.ahk

#NoEnv
#SingleInstance Off
#Persistent
#NoTrayIcon
#WinActivateForce

If !pToken := Gdip_Startup()
{
	MsgBox, 48, Gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit
;Variables
NotFullscreen := True
onDrawing := False
onChanging := False
isPause := False

;Create Bitmaps from Zip-with-frames-Files
UgoiraZip :=  RegExReplace(A_ScriptName, "i).ahk$", ".zip" )  
File := FileOpen( UgoiraZip , "r")
FileGetSize, fsize , %UgoiraZip%
VarSetCapacity(Buffer, fsize, 0)

;Pointer  Int64, UInt, Int, UShort, Short, UChar, Char, Double, Float, UPtr or Ptr
;         64bit |   32bit |    16bit     |8bitReadAsNum| 64bit| 32bit |pointer to str  
;NumGet() will return any thing in decimal number
;memory address must in [  &mem  ] or  [  addr + 0  ] , mem is memory block object,
;addr := &mem addr store pointer address of memory block object ,but when pass it to NumGet()
;It must be written in [ addr + 0  ] <--- this [ + 0 ] must be written .

File.RawRead( &Buffer, fsize)
;Now I have a copy in memory , file reader can close.
File.Close()
NumOfAllFile := NumGet( &Buffer, fsize-14, "UShort")
listOffset := NumGet( &Buffer, fsize-6, "UInt")
next := listOffset
Loop %NumOfAllFile%
{       
        fileOffset%A_Index% := NumGet( &Buffer, next + 42 , "UInt")
        fileLen%A_Index% := NumGet( &Buffer, next + 20 , "UInt")
        nameLen%A_Index% := NumGet( &Buffer, next + 28 , "UShort")
        fileExtSkip := NumGet( &Buffer, next + 30 , "UShort")
        next := next + 46 + nameLen%A_Index% + fileExtSkip
}
fileWithoutDir := 0
Loop %NumOfAllFile%
{
        if ( 0 = fileLen%A_Index% )
        {
        continue
        }
        else {
        fileWithOutDir := fileWithOutDir + 1
        ;create memory for Gdiplus.dll store bitmap
        hData%fileWithOutDir% := DllCall("GlobalAlloc", "Uint", 2, "Uint", fileLen%A_Index% )
        ;none type pointer and protect in-use memory
        pData := DllCall("GlobalLock", "Uint", hData%fileWithOutDir%)
        ;address of image file start
        pointer := &Buffer + fileOffset%A_Index% + 30 + nameLen%A_Index%
        ;use none type pointer copy image file content to the new empty mem for Gdiplus.dll which just create before
        DllCall("RtlMoveMemory", "Uint", pData, "Uint", pointer , "Uint", fileLen%A_Index% )
        ;delete none type pointer and unlock
        DllCall("GlobalUnlock", "Uint", hData%fileWithOutDir%)
        ;create Stream type pointer for Gdiplus.dll to read
        DllCall("ole32\CreateStreamOnHGlobal", "Uint", hData%fileWithOutDir%, "int", True, "UintP", pStream)
        ;give Gdiplus.dll Stream pointer ,then get Bitmap pointer which AHK GUI can use.
        ;By the way, Gdiplus.dll Stream pass can handle png jpg bmp decode to Bitmap, which GUI can directly use.
        DllCall("Gdiplus.dll\GdipCreateBitmapFromStream", "Uint", pStream, "UintP", pBmp)
	pBitmap%fileWithOutDir% := pBmp
        }
}
;All image date have been copied to Gdiplus.dll , this can be clear.
;Gdiplus.dll use GlobalAlloc created memory space (public address).
;So don't do this -->  DllCall("GlobalFree", "Uint", hData)
VarSetCapacity(Buffer, 0) 

;Dimensions of the images
nWidth := Gdip_GetImageWidth(pBitmap1)
nHeight := Gdip_GetImageHeight(pBitmap1)
nWidthOri := nWidth
nHeightOri := nHeight

Random, RandomIDaddTitle, 111111, 999999
myTitle := A_ScriptName RandomIDaddTitle
;Create a GUI
Gui, 1: -Caption +E0x80000 +LastFound -OwnDialogs -Owner +AlwaysOnTop
Gui, 1: Show
hwnd1 := WinExist()
WinActivate, ahk_id %hwnd1%
WinSetTitle, %myTitle%

;autofit size calculate
;screen working area ( area without taskbar )
SysGet, MonitorPrimary, MonitorPrimary
SysGet, WA, MonitorWorkArea, %MonitorPrimary%
WAWidth := WARight-WALeft
WAHeight := WABottom-WATop
aspectScr := Round( (A_ScreenWidth / A_ScreenHeight) , 4 )
aspectWA := Round( (WAWidth / WAHeight) , 4 )
aspectPic := Round( (nWidthOri / nHeightOri) , 4 )
if ( aspectPic > aspectScr )
{
  Ratio := Round( (A_ScreenWidth / nWidthOri) , 4 )
}
else
{
  Ratio := Round( (A_ScreenHeight / nHeightOri) , 4 )
}
;Reszie causing drawing delay
antiFullScrDelay := 30
antiResizeDelay := 0
if  ( aspectPic > aspectWA )
{
  if  ( nWidthOri > WAWidth )
  {
    RatioW := Round( (WAWidth / nWidthOri) , 4 )
    nWidth := Round( nWidthOri * RatioW, 0) 
    nHeight := Round( nHeightOri * RatioW, 0) 
    antiResizeDelay := 30
  }
}
else
{
  if  ( nHeightOri > WAHeight )
  {
    RatioW := Round( (WAHeight / nHeightOri) , 4 )
    nWidth := Round( nWidthOri * RatioW, 0) 
    nHeight :=  Round( nHeightOri * RatioW, 0) 
    antiResizeDelay := 30
  }  
}

nFWidth :=  Round( nWidthOri * Ratio, 0) 
nFHeight :=  Round( nHeightOri * Ratio, 0) 
fX:= (A_ScreenWidth - nFWidth)//2
fY:= (A_ScreenHeight - nFHeight)//2
X:= (WAWidth - nWidth)//2
Y:= (WAHeight - nHeight)//2
hbm := CreateDIBSection(nWidth, nHeight) 
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetInterpolationMode(G, 7)


;Brush for drawing fullscreen black background
pBrush := Gdip_BrushCreateHatch(0xff000000, 0xff000000, Brush)

;https://autohotkey.com/board/topic/38446-getting-lparam-bits-from-wm-keydown/
OnMessage(0x101, "WM_KEYUP") 
;Make left mouse button down event become drag event. 
OnMessage(0x201, "WM_LBUTTONDOWN")
;Toggle pause
OnMessage(0x204, "WM_RBUTTONDOWN") 
;Toggle Fullscreen
OnMessage(0x208, "WM_MBUTTONUP") 
;Scroll Wheel change frame while pause
OnMessage(0x20A, "WM_MOUSEWHEEL")
;Xbutton change frame while pause
OnMessage(0x20C, "WM_XBUTTONUP")


modNum := fileWithoutDir + 1
; Do a move first else the WinGetPos() in loop will cause problem.
WinMove,%myTitle%, , X, Y
;Loop with manual control index , so the index is globally accessable.

Animate:
frame := 1
PlayLoop:
if ( frame > fileWithOutDir )
{
    Goto, Animate
}

    If NotFullscreen	;NotFullscreen
    {
        if not onChanging
        {
        onDrawing := True
          Gdip_DrawImage(G, pBitmap%frame%, 0, 0, nWidth, nHeight, 0, 0, nWidthOri, nHeightOri)
          WinGet id, ID, A
          if (id = hwnd1 )
          {
                    WinGetPos, X, Y, , , %myTitle%
          }
          UpdateLayeredWindow(hwnd1, hdc, X, Y, nWidth, nHeight )
          Gdip_GraphicsClear(G)
	  if not isPause
          {
            frame := frame + 1
          }
        onDrawing := False
        }
        Sleep 50 - antiResizeDelay
    }
    Else	;Fullscreen
    {
        if not onChanging
        {
        onDrawing := True
          DllCall("gdiplus\GdipFillRectangle", "uint", GF, "int", pBrush, "float", 0, "float", 0, "float", A_ScreenWidth, "float", A_ScreenHeight)
          Gdip_DrawImage(GF, pBitmap%frame%, fX, fY, nFWidth, nFHeight, 0, 0, nWidthOri, nHeightOri)
          UpdateLayeredWindow(hwnd1, hdcF, 0, 0, A_ScreenWidth, A_ScreenHeight )
          Gdip_GraphicsClear(GF)
	  if not isPause
          {
            frame := frame + 1
          }
        onDrawing := False
        }
        Sleep 50 - antiFullScrDelay
    }
Goto, PlayLoop
Return

;Exit
;for taskbar close, else it will left autohotkey.exe running in background
GuiClose:
playerEND()
return

Exit:
playerEND()
ExitApp


playerEND()
{
        Global
        Loop %fileWithOutDir%
        {
               DllCall("GlobalFree", "Uint", hData%A_Index% )
        }
        SelectObject(hdcF, obmF), DeleteObject(hbmF)
        DeleteDC(hdcF), Gdip_DeleteGraphics(GF)
	SelectObject(hdc, obm), DeleteObject(hbm)
	DeleteDC(hdc), Gdip_DeleteGraphics(G)
	Gdip_DeleteBrush(pBrush), Gdip_Shutdown(pToken)
        ExitApp
}

frameUP()
{
Global
  onChanging := True
    frame := frame + 1
    if frame >= modNum
    {
        frame := ( Mod(frame, modNum)  + 1)
    }
  onChanging := False
}

frameDOWN()
{
Global
  onChanging := True
    frame := frame - 1
    if frame <= 0
    {
        frame := Mod(  (modNum + frame -1) , modNum)
    }
  onChanging := False
}



WM_KEYUP(wParamk, lParamk )
{
Global
  if (wParamk = 27)  ; ESC
  {
    playerEND()
  }
  else if isPause
  {
      if (wParamk = 34)  ; PageDown
      {
          frameUP()
      }
      else if (wParamk = 33)   ; PageUP
      {
          frameDOWN()
      } 
  }
}
WM_XBUTTONUP(wParamX, lParamX)
{
Global
  if isPause
  {
  whichK := NumGet(&wParamX, 0, "Short")
      if (whichK = 49)  ; Xbutton2
      {
          frameUP()
      }
      else if (whichK = 54) ; Xbutton1
      {
          frameDOWN()
      } 
  }
}


;https msdn.microsoft.com /en-us/library/windows/desktop/ms644970(v=vs.85).aspx  Broken Link for safety
;https://autohotkey.com/boards/viewtopic.php?t=9247      <--- I copied the wheel code part then got crash.
;https://autohotkey.com/board/topic/98112-wheel-and-drag-deincrement-edit-controls-with-the-mouse/
WM_MOUSEWHEEL(wParamS, lParamS)
{
Global
  if isPause
  {
    ; wParam length represent for scroll up or down? I don't know.
    ; Seen like scrolling down will use more bytes , large than 7.
    ; Notice I use scrolling DOWN to frameUP() , when DOING frameUP() the WHEEL IS GOING DOWN
      if (StrLen(wParamS)>7)
      {
          frameUP()
      }
      else
      {
          frameDOWN()
      } 
  }
}

;Toggle Pause
WM_RBUTTONDOWN()
{
        Global
	if isPause
        {
          isPause := False
        }
        else
        {
          isPause := True
        }
}

; Make left mouse button down event become drag event. 
; So normal click is not exist, how to have both event normal like a title bar, I don't know.
; Keep Rbutton down then click Lbutton Toggle Fullscreen
; While Fullscreen disable sending drag event make GUI unmovable.
; Don't use change window attribute Flag like that thread:
; https://autohotkey.com/board/topic/70123-disable-gui-move/
; Unless your don't want to move it again, set back to movable can't make GUI back to normal.
; Every time GUI lost then get focus again , GUI will be send back to x=0, y=0 again.
WM_LBUTTONDOWN(wParamL, lParamL)
{
Global
        if NotFullscreen
       {
	        PostMessage, 0xA1, 2
       }
       if ( (StrLen(wParamL)=1 )  && (NumGet(&wParamL, 0, "Short")=51)  )
       {
                playerEND()
       }
}

;Toggle Fullscreen
WM_MBUTTONUP()
{
	Global
        If NotFullscreen	; turn into Fullscreen
        {
            loop onDrawing 
            {
            Sleep 17
            }
            onChanging := True
                WinGetPos, X, Y, , , %myTitle%
                SelectObject(hdc, obm), DeleteObject(hbm)
                DeleteDC(hdc), Gdip_DeleteGraphics(G)

                hbmF := CreateDIBSection(A_ScreenWidth, A_ScreenHeight) 
                hdcF := CreateCompatibleDC()
                obmF := SelectObject(hdcF, hbmF)
                GF := Gdip_GraphicsFromHDC(hdcF)
                Gdip_SetInterpolationMode(GF, 7)
                NotFullscreen := False
                WinActivate, ahk_id %hwnd1%
            onChanging := False
        }
        Else		; turn into NotFullscreen
        {
            loop onDrawing 
            {
            Sleep 17
            }
            onChanging := True
                SelectObject(hdcF, obmF), DeleteObject(hbmF)
                DeleteDC(hdcF), Gdip_DeleteGraphics(GF)

                hbm := CreateDIBSection(nWidth, nHeight) 
                hdc := CreateCompatibleDC()
                obm := SelectObject(hdc, hbm)
                G := Gdip_GraphicsFromHDC(hdc)
                Gdip_SetInterpolationMode(G, 7)
;Draw a first frame then move , makes shrinking look better, this part of code can be remove .
                Gdip_DrawImage(G, pBitmap%frame%, 0, 0, nWidth, nHeight, 0, 0, nWidthOri, nHeightOri)
                UpdateLayeredWindow(hwnd1, hdc, X, Y, nWidth, nHeight )
                Gdip_GraphicsClear(G)
            onChanging := False
            WinActivate, ahk_id %hwnd1%
            NotFullscreen := True
            WinMove, %myTitle%,, X, Y
        }
}


could someone please help me. I use a new .txt file put the codes into it, change extension to .ahk then i rename it to hulagirl.ahk, downloaded and installed latest version of AHK.

i have a bunch of .jpg files, zip them all together with store uncompressed and rename that .zip file to hulagirl.zip. put the zip and ahk file into same folder and run .ahk but nothings happening except i see ahk in my windows taaskbar.

what am i missing here? (i am also using gdip_all.ahk that i downloaded from here "https://autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/" and rename it to gdip.ahk put into same folder as hulagirl.ahk).

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 322 guests