Page 1 of 2

[Module] Animated PNG (all OS)

Posted: Sat Apr 25, 2020 10:27 am
by Thorsten1867
Animated PNG - Module (all OS / 64Bit)

Code: Select all

; PNG::AddFrames()         ; comparable with 'AddImageFrame()', but for all frames of the APNG

; PNG::ResetFrames()       ; sets the frame index before the first frame
; PNG::DrawFrame()         ; draws the current frame
; PNG::ScaleFrames()       ; scales the output of the frames

; PNG::Load()              ; comparable with 'LoadImage()'
; PNG::Save()              ; comparable with 'SaveImage()', but with all frames

; PNG::Create()            ; create an APNG from the image
; PNG::AddFrame()          ; add an image as frame
; PNG::Close()             ; finishes the creation and saves the APNG

; PNG::FrameCount()        ; comparable with 'ImageFrameCount()'
; PNG::FrameID()           ; comparable with 'ImageID()', but for the current Frame of the image

; PNG::GetFrame()          ; comparable with 'GetImageFrame()'
; PNG::GetFrameDelay()     ; comparable with 'GetImageFrameDelay()'
; PNG::GetFrameWidth()     ; comparable with 'ImageWidth'
; PNG::GetFrameHeight()    ; comparable with 'ImageHeight'
; PNG::GetFrameAttribute() ; [#OffsetX/#OffSetY/#Dispos/#Blend/#DelayNum/#DelayDen]

; PNG::GetLoop()           ; returns current loop
; PNG::LoopCount()         ; returns number of times to loop OR 0 for infinite loop

; PNG::SetFrame()          ; comparable with 'SetImageFrame()'
; PNG::SetTimer()          ; changes the delay of the timer
  
; PNG::StartTimer()        ; starts the timer to play the frames
; PNG::PauseTimer()        ; pauses or resumes the timer
; PNG::StopTimer()         ; stops the timer
Download: UseAPNGModule.pbi

Re: [Module] Animated PNG (all OS)

Posted: Sat Apr 25, 2020 4:45 pm
by VB6_to_PBx
How to make the Elephant.png walk continously ? ... and with smooth transitions from beginning -to- end / end-to- beginning , in an endless Loop ??

Also ... great work with APNG !!!! ... many Thanks for your example !

Re: [Module] Animated PNG (all OS)

Posted: Sat Apr 25, 2020 5:30 pm
by chi
Thanks for sharing, Thorsten!

In the example, call SetFrame before GetFrameAttribute #Offset...

Code: Select all

PNG::SetFrame(#Image, Frame)

OffsetX = PNG::GetFrameAttribute(#Image, PNG::#OffsetX)
OffsetY = PNG::GetFrameAttribute(#Image, PNG::#OffsetY)
VB6_to_PBx wrote:How to make the Elephant.png walk continously ?
Just comment ;RemoveWindowTimer(#Windows, #Timer)

Re: [Module] Animated PNG (all OS)

Posted: Sat Apr 25, 2020 6:24 pm
by infratec
Did a short test.

With this constellation the flickering is a bit reduced.
So it depends also on the order of the commands.

Code: Select all

EnableExplicit

#Windows = 1

#Image1 = 1
#Image2 = 2

#Gadget1  = 1
#Gadget2  = 2

#Timer1   = 1
#Timer2   = 2

IncludeFile "UseAPNGModule.pbi"


Define.i Event, Frame1, Frame2
Define.i OffsetX1, OffsetY1, OffsetX2, OffsetY2


UsePNGImageDecoder()

PNG::Load(#Image1, "Elephant.png")

PNG::Load(#Image2, "Elephant.png")

;https://de.wikipedia.org/wiki/Datei:Animated_PNG_example_bouncing_beach_ball.png
;PNG::Load(#Image2, "Animated_PNG_example_bouncing_beach_ball.png")

If OpenWindow(#Windows, 0, 0, 1010, 425, "ImageGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ImageGadget(#Gadget1, 10, 10, 280, 280, #False)
  ImageGadget(#Gadget2, 510, 10, 280, 280, #False)
  
  If PNG::FrameCount(#Image1) > 1
    AddWindowTimer(#Windows, #Timer1, PNG::GetFrameDelay(#Image1, Frame1))
  EndIf
  
  If PNG::FrameCount(#Image2) > 1
    Frame2 = PNG::FrameCount(#Image2) / 2
    AddWindowTimer(#Windows, #Timer2, PNG::GetFrameDelay(#Image1, Frame2))
  EndIf
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Timer 
        
        Select EventTimer()
            
          Case #Timer1
            
            PNG::SetFrame(#Image1, Frame1)
            SetGadgetState(#Gadget1, PNG::FrameID(#Image1))
            
            OffsetX1 = PNG::GetFrameAttribute(#Image1, PNG::#OffsetX)
            OffsetY1 = PNG::GetFrameAttribute(#Image1, PNG::#OffsetY)
            
            ResizeGadget(#Gadget1, 10 + OffsetX1, 10 + OffsetY1, #PB_Ignore, #PB_Ignore)
            
            Frame1 + 1
            If Frame1 = PNG::FrameCount(#Image1)
              Frame1 = 0
            EndIf
            AddWindowTimer(#Windows, #Timer1, PNG::GetFrameDelay(#Image1, Frame1))
            
          Case #Timer2
            
            PNG::SetFrame(#Image2, Frame2)
            SetGadgetState(#Gadget2, PNG::FrameID(#Image2))
            
            OffsetX2 = PNG::GetFrameAttribute(#Image2, PNG::#OffsetX)
            OffsetY2 = PNG::GetFrameAttribute(#Image2, PNG::#OffsetY)
            
            ResizeGadget(#Gadget2, 510 + OffsetX2, 10 + OffsetY2, #PB_Ignore, #PB_Ignore)
            
            Frame2 + 1
            If Frame2 = PNG::FrameCount(#Image2)
              Frame2 = 0
            EndIf
            AddWindowTimer(#Windows, #Timer2, PNG::GetFrameDelay(#Image2, Frame2))
            
        EndSelect
        
    EndSelect
    
  Until Event = #PB_Event_CloseWindow
  
EndIf
I also set the timer per frame delay.

Re: [Module] Animated PNG (all OS)

Posted: Sat Apr 25, 2020 7:09 pm
by Thorsten1867
Update: PNG::Save() - Save image with all frames as APNG.

Re: [Module] Animated PNG (all OS)

Posted: Sat Apr 25, 2020 8:26 pm
by VB6_to_PBx
VB6_to_PBx wrote:How to make the Elephant.png walk continously ?
Just comment ;RemoveWindowTimer(#Windows, #Timer)[/quote]

i had commented that Line out , but thats when i discovered it caused a jumping jitter effect when it Looped back to beginning Frame :(

i just left that line commented,
but then changed this :

Code: Select all

            Frame + 1
            If Frame >= PNG::FrameCount(#Image)
              Frame = 0
              ;RemoveWindowTimer(#Windows, #Timer)
            EndIf 
to this and it seems to now act very close to same Elephant.png opened in IrfanView software
Frame = 1 instead of Frame = 0

Code: Select all

            Frame + 1
            If Frame >= PNG::FrameCount(#Image)
              Frame = 1
              ;RemoveWindowTimer(#Windows, #Timer)
            EndIf 
            
          EndIf 

Re: [Module] Animated PNG (all OS)

Posted: Sat Apr 25, 2020 8:35 pm
by Andre
Interesting project, thanks for sharing! :D

It would be nice, if the flickering in the demo code could be avoided...

Re: [Module] Animated PNG (all OS)

Posted: Sat Apr 25, 2020 8:47 pm
by Fred
Nice module ! Using a CanvasGadget will remove the flicker

Re: [Module] Animated PNG (all OS)

Posted: Sat Apr 25, 2020 8:51 pm
by Thorsten1867
Example now uses the CanvasGadget

Re: [Module] Animated PNG (all OS)

Posted: Sun Apr 26, 2020 10:01 am
by Thorsten1867
Example: Convert a GIF to APNG

Re: [Module] Animated PNG (all OS)

Posted: Sun Apr 26, 2020 1:14 pm
by chi
There are some problems with selfmade APNG's (samples.zip)
Btw. Your module works on Windows with x86 and x64
Also, with your latest example: #Example = 0 doesn't show anything

Re: [Module] Animated PNG (all OS)

Posted: Sun Apr 26, 2020 9:15 pm
by Thorsten1867
chi wrote:There are some problems with selfmade APNG's (samples.zip)
Btw. Your module works on Windows with x86 and x64
Also, with your latest example: #Example = 0 doesn't show anything
This is just a very simple example code.
Try it with 'ImageEx', there is a real player integrated.

Re: [Module] Animated PNG (all OS)

Posted: Mon Apr 27, 2020 12:25 am
by chi
Oh okay, thanks anyway!

Re: [Module] Animated PNG (all OS)

Posted: Mon Apr 27, 2020 5:19 pm
by Thorsten1867
Update:
  • PNG::ResetFrames() - sets the frame index before the first frame
  • PNG::DrawFrame() - draws the current frame
  • PNG::ScaleFrames() - scales the output of the frames
  • PNG::GetLoop() - returns current loop
  • PNG::SetTimer() - changes the delay of the timer
  • PNG::StartTimer() - starts the timer to play the frames
  • PNG::PauseTimer() - pauses or resumes the timer
  • PNG::StopTimer() - stops the timer

Re: [Module] Animated PNG (all OS)

Posted: Wed Apr 29, 2020 12:31 pm
by Thorsten1867
Bugfixes: Problems with indexed PNGs and complex APNGs (e.g. #APNG_Dispos_OP_Previous) fixed.