- PNG::Create(ImageNum.i, File.s, Loops.i=0, Delay.i=0, Flags.i=#False)
- PNG::AddFrame(ImageNum.i, FrameNum.i, X.i=0, Y.i=0, Width.i=0, Height.i=0, Delay.i=0, Dispos_OP.i=0, Blend_OP.i=0, Index.i=#PB_Default)
- PNG::Close(ImageNum.i)
[Module] Animated PNG (all OS)
- Thorsten1867
- Addict
- Posts: 1366
- Joined: Wed Aug 24, 2005 4:02 pm
- Location: Germany
Re: [Module] Animated PNG (all OS)
Update: create own APNGs
Translated with http://www.DeepL.com/Translator
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
Re: [Module] Animated PNG (all OS)
Thank youThorsten1867 wrote:Bugfixes: Problems with indexed PNGs and complex APNGs (e.g. #APNG_Dispos_OP_Previous) fixed.
Et cetera is my worst enemy
- Kwai chang caine
- Always Here
- Posts: 5357
- Joined: Sun Nov 05, 2006 11:42 pm
- Location: Lyon - France
Re: [Module] Animated PNG (all OS)
Works nice here, thanks for sharing
The happiness is a road...
Not a destination
Not a destination
- Thorsten1867
- Addict
- Posts: 1366
- Joined: Wed Aug 24, 2005 4:02 pm
- Location: Germany
Re: [Module] Animated PNG (all OS)
Bugfixes: GenerateFrames()
Translated with http://www.DeepL.com/Translator
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
- Thorsten1867
- Addict
- Posts: 1366
- Joined: Wed Aug 24, 2005 4:02 pm
- Location: Germany
Re: [Module] Animated PNG (all OS)
Bugfix: GenerateFrames() without scaling
Translated with http://www.DeepL.com/Translator
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
Download of PureBasic - Modules
Download of PureBasic - Programs
[Windows 11 x64] [PB V5.7x]
- Andre
- PureBasic Team
- Posts: 2071
- Joined: Fri Apr 25, 2003 6:14 pm
- Location: Germany (Saxony, Deutscheinsiedel)
- Contact:
Re: [Module] Animated PNG (all OS)
The following is the result of a collaboration between GFX_Wizzard_BF author and 'Thorsten1867', creating "Sprite sheets" made from APNG images:
walbus wrote:Save as 'Create_Sprite_CSS_Sheet_from_APNG.pb' ('UseAPNGModule.pbi' include is needed)
SpriteSheets_BF support 24 bit, 32 bit and alpha channel so there is no loss.
Depending on the template, the use of JPEG-based SpriteSheets_BF and Sprites_BF can save up to 80% in size, but this really depends on the template and can be very different.
SpriteSheets_BF can of course also be created as PNG.
All sprite data are stored in the sprite sheets, including delays, invisible color and color distance.
This data can be read in and used automatically.
Code: Select all
; Create a SpriteSheet_BF from a APNG image
; For GFX_Wizzard_BF or other, with included frame data and external sheet-info file
; Author W. Albus and Thorsten Hoeppner (Thorsten1867) - This code is free
; The APNG module for Purebasic from Thorsten1867 is needed
; https://www.purebasic.fr/english/viewtopic.php?f=27&t=75172
; - Or search simple on Google for it
; Recommended : Look ever for the newest APNG module version
XIncludeFile "UseAPNGModule.pbi"
DeclareModule CreateCSSSheet_from_APNG_BF
Declare CreateCSSSheet_from_APNG_BF(Path_Source$, Scale.f = 1, Get_Only_Sheet_ID = #False)
EndDeclareModule
Module CreateCSSSheet_from_APNG_BF
EnableExplicit
Macro Common_Write_Frame_Data ; Change on this macro absolutely nothing
WriteStringN(File, " Frames #" + RSet(Str(Frames), 8, "0 "), #PB_Ascii)
WriteStringN(File, " Frame width #" + RSet(Str(aPNG_Width), 8, "0 "), #PB_Ascii)
WriteStringN(File, " Frame height #" + RSet(Str(aPNG_Height), 8, "0 "), #PB_Ascii)
WriteStringN(File, " Sheet width #" + RSet(Str(Sheet_Width), 8, "0 "), #PB_Ascii)
WriteStringN(File, " Sheet height #" + RSet(Str(Sheet_Height), 8, "0 "), #PB_Ascii)
WriteStringN(File, " Frames in a row #" + RSet(Str(Frames_in_a_Row), 8, "0 "), #PB_Ascii)
WriteStringN(File, " Invisible color #" + "00000000" + " $000000", #PB_Ascii)
WriteStringN(File, " Color distance #" + "00000000" + " $000000", #PB_Ascii)
For i=0 To Frames -1
SetImageFrame(aPNG_ID, i)
Frame_Delay = GetImageFrameDelay(aPNG_ID)
Result = WriteStringN(File, " Frame / delay :" + RSet(Str(i + 1), 8, "0 ") +
" *" + RSet(Str(Frame_Delay), 8, "0"), #PB_Ascii)
Next i
EndMacro
Procedure CreateCSSSheet_from_APNG_BF(Path_Source$, Scale.f = 1, Get_Only_Sheet_ID = #False)
Define.i aPNG_ID, aPNG_Width, aPNG_Height
Define.i Frames, Frames_X, Frames_Y, Frames_in_a_Row, Frame_Delay
Define.i Sheet_ID, Sheet_Width, Sheet_Height
Define.i i, add_height_0, add_height_1, X, Y, cHeight, Result, File, File_Length
Define.s Path_Destination$
If Path_Source$ = ""
ProcedureReturn 0
EndIf
If UCase(GetExtensionPart(Path_Source$)) <> "PNG"
ProcedureReturn -1
EndIf
aPNG_ID = PNG::Load(#PB_Any, Path_Source$)
If IsImage(aPNG_ID) ;{ Create sheet from apng
aPNG_ID = PNG::GenerateFrames(aPNG_ID, Scale)
PNG::Free(aPNG_ID) ; The original image frames from APNG are no longer required
aPNG_Width = ImageWidth(aPNG_ID)
aPNG_Height = ImageHeight(aPNG_ID)
Frames = ImageFrameCount(aPNG_ID)
If Frames > 1
If aPNG_Height > aPNG_Width
Frames_X = Sqr(Frames) + 1
Else
Frames_X = Sqr(Frames)
EndIf
If Not Frames_X : Frames_X = 1 : EndIf
Frames_Y = Frames / Frames_X + 1
Sheet_Width = Frames_X * aPNG_Width
Sheet_Height = Frames_Y * aPNG_Height
For i = 0 To Frames - 1 ;{ Calculations
add_height_1 = add_height_0 : X + aPNG_Width
If X => Sheet_Width
X = 0
add_height_0 + aPNG_Height
EndIf ;}
Next
sheet_height = add_height_1 + aPNG_Height
Frames_in_a_Row = Sheet_Width / aPNG_Width
Sheet_ID = CreateImage(#PB_Any, Sheet_Width, Sheet_Height, 32, #PB_Image_Transparent)
If IsImage(Sheet_ID)
X = 0 : Y = 0
If StartDrawing(ImageOutput(Sheet_ID)) ;{ Draw sheet image
For i = 0 To Frames - 1
SetImageFrame(aPNG_ID, i)
DrawingMode(#PB_2DDrawing_AlphaBlend)
DrawImage(ImageID(aPNG_ID), X, Y)
X + aPNG_Width
If X = > Sheet_Width
X = 0
Y + aPNG_Height
EndIf
Next
StopDrawing()
EndIf ;}
If Get_Only_Sheet_ID : ProcedureReturn Sheet_ID : EndIf
Path_Destination$ = GetPathPart(Path_Source$) +
GetFilePart(Path_Source$, #PB_FileSystem_NoExtension) +
"_SpriteSheet_BF.png"
If Path_Destination$
SaveImage(Sheet_ID, Path_Destination$, #PB_ImagePlugin_PNG)
EndIf
FreeImage(Sheet_ID)
Else
ProcedureReturn -2
EndIf
Else
ProcedureReturn -3
EndIf
Else
ProcedureReturn -4
EndIf ;}
; This are pre defined import functions for use this code directly
; - inside the GFX_Wizzard_BF main module to import a APNG image as SpriteSheet_BF
; SetGIFandCSS_Frames_BF(Frames)
; SetGIFandCSS_Frame_width_BF(aPNG_Width)
; SetGIFandCSS_Frame_height_BF(aPNG_Height)
; SetCSS_width_BF(sheet_width)
; SetCSS_height_BF(Sheet_Height)
; SetFrames_in_a_row_BF(Frames_in_a_Row)
; SetGIFandCSS_color_distance_BF(0)
; SetGIFandCSS_invisible_color_BF(0)
; For i = 0 To Frames -1
; SetImageFrame(aPNG_ID, i)
; Frame_Delay = GetImageFrameDelay(aPNG_ID)
; SetGIFandCSS_delay_array_BF(i, Frame_Delay)
; Next i
; ProcedureReturn Sheet_ID
If Path_Destination$
File = CreateFile(#PB_Any, GetPathPart(Path_Destination$) +
GetFilePart(Path_Destination$, #PB_FileSystem_NoExtension) +
"_sheet_info_BF.txt")
If File ;{ Write sheet info file
Common_Write_Frame_Data
CloseFile(File)
Else
ProcedureReturn -5
EndIf ;}
If FileSize(Path_Destination$) > 0 ;{ Append file to the image
File = OpenFile(#PB_Any, Path_Destination$)
If File
File_Length = Lof(File)
FileSeek(File, File_length)
Common_Write_Frame_Data
Result = WriteQuad(File, Loc(File) - File_length)
CloseFile(File)
EndIf
If Result = 8 : ProcedureReturn #True : EndIf
EndIf ;}
EndIf
ProcedureReturn -6
EndProcedure
EndModule
;- ======== Module - Example ========
CompilerIf #PB_Compiler_IsMainFile
UsePNGImageDecoder()
UseModule CreateCSSSheet_from_APNG_BF
EnableExplicit
Define Get_Only_Sheet_ID = #False ; Get only the Sheet_ID for displaying
; - the created sheet without creating a file
Define scale.f = 1.0 ; Scaling factor
Define Path_Source$ = OpenFileRequester("Select a APNG picture", "", "", 0)
Define Sheet_ID = CreateCSSSheet_from_APNG_BF(Path_Source$, scale, get_only_Sheet_ID)
If (get_only_sheet_ID And Not IsImage(sheet_ID)) Or sheet_ID < 1
If sheet_ID = -1 Or sheet_ID = -3
MessageRequester("Hint", "Not a multiframe APNG image" + #LF$ + #LF$ + Str(sheet_ID))
ElseIf sheet_ID < 0
MessageRequester("Hint", "Function fail" + #LF$ + #LF$ + Str(sheet_ID))
EndIf
End
EndIf
If get_only_Sheet_ID
Define window_ID = OpenWindow(#PB_Any, 0, 0, 1200, 700,
"APNG based SpriteSheet_BF generating for GFX_Wizzard_BF and other",
#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define canvas_ID = CanvasGadget(#PB_Any, 0, 0, 1200, 700)
ResizeImage(sheet_ID, 1200, 700)
If StartDrawing(CanvasOutput(canvas_ID))
DrawingMode(#PB_2DDrawing_AlphaBlend)
DrawImage(ImageID(Sheet_ID), 0, 0)
StopDrawing()
EndIf
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
CompilerEndIf