LLGif89aDecoder низкоуровневый инструмент,декодирующий все поля файлов формата GIF89a в нативные структуры Godot
установка:
- скачайте и положите gif89a.gd в любое место в вашем godot проекте
- готово
для воспроизведение гиф добавьте к Node2D скрипт со следующим содержанием:
extends Node2D
var gif_player : LLGif89aDecoder.GifPlayer = null
func _ready() -> void:
var data : LLGif89aDecoder.GifData = LLGif89aDecoder.read_gif_from_path("путь к гиф.gif")
if data.has_error : return
gif_player = data.Gif_Player
gif_player.set_canvas_item(self)готово! гиф воспроизведётся при запуске сцены.
для чтения гиф с буфера замените
var data : LLGif89aDecoder.GifData = LLGif89aDecoder.read_gif_from_path("путь к гиф.gif")на
var f : FileAccess = FileAccess.open("путь к гиф.gif",FileAccess.READ)
var data : LLGif89aDecoder.GifData = LLGif89aDecoder.read_gif_from_buffer(f.get_buffer(f.get_length()))альтернативный минимальный вариант воспроизведения гиф без использования GifPlayer:
#быстрый старт: воспроизведение гиф без использования GifPlayer с помощью LLGif89aDecoder (godot 4.5.1+)
extends Node2D
#данные фреймов
var gif_delta : PackedFloat64Array = []
var gif_image : Array[ImageTexture] = []
var gif_position : PackedVector2Array = []
var gif_disposal : PackedByteArray = []
var gif_full_size : Vector2i = Vector2i(2,2)
var gif_background_color : Color = Color(1,1,1,0)
var time : float = 0.0
var full_time : float = 0.0
func _ready() -> void:
var data : LLGif89aDecoder.GifData = LLGif89aDecoder.read_gif_from_path("G:/delete/jumping_through_windows.gif")
if data.has_error : return #проверяем,есть ли ошибки
gif_delta = data.get_converted_delta()
gif_image = data.get_image_textures()
gif_position = data.get_position()
gif_disposal = data.get_disposal()
gif_full_size = Vector2i(data.Canvas_Width,data.Canvas_Height)
gif_background_color = data.background_color
for i in gif_delta:
full_time += i
func _process(delta: float) -> void:
time = wrapf(time + delta,0.0,full_time)
queue_redraw()
func _draw() -> void:
var local_time : float = time
for i in gif_delta.size():
local_time -= gif_delta[i]
match gif_disposal[i]:
2: #очистить до фона
draw_rect(Rect2i(Vector2.ZERO,gif_full_size),gif_background_color)
3: #вернуться к предыдущему фрейму
if local_time < 0.0:
draw_texture(gif_image[i],gif_position[i])
_: #0 - метод не требует освобождения,1 - оставить текущее изображение и нарисовать следующее поверх него,4-7 поведение не определено
draw_texture(gif_image[i],gif_position[i])
if local_time < 0.0 : breakкласс GifPlayer - предназначен для простого вопроизведения gif
методы:
set_canvas_item(new_canvas_item :
set_speed_scale(new_speed_scale :
set_offset(new_offset :
set_rotation(new_rotation :
set_rotation_degrees(new_rotation_degress :
set_scale(new_scale :
set_transform(new_transform :
класс LLGif89aDecoder:
enum THREAD_MODE {current,auto,low_priority,high_priority}
THREAD_MODE.current - декодирование выполняется в том же потоке,который вызвал метод
THREAD_MODE.auto - декодирование выполняется на оптимальном кол-ве потоков (6)
THREAD_MODE.low_priority - декодирование выполняется с присвоением high_priority = false,по умолчанию будут задействованы 30% потоков (ProjectSettings.threading/worker_pool/low_priority_thread_ratio)
THREAD_MODE.high_priority - декодирование выполняется с присвоением high_priority = true этот режим будет использовать все потоки,используйте THREAD_MODE.high_priority только если знаете,что делаете,при большом размере gif режим THREAD_MODE.high_priority может вызвать промахи кэша из-за чего итоговое время обработки может оказаться заметно дольше,чем при режиме THREAD_MODE.auto
аргументы метода read_gif_from_path
path :
аргументы метода read_gif_from_buffer
buffer :
generate_gif_player :
_generate_image :
thread_mode : LLGif89aDecoder.THREAD_MODE = THREAD_MODE.auto - режим распараллеливания декодирования gif
print_unknown_markers :
print_comment :
поля которые будут тут или тут будут помечены кликабельными ссылками,тут же будет краткое описание при необходимости
класс GifData - хранит в себе все поля gif:
методы:
get_image_textures() ->
get_unconverted_delta() ->
get_converted_delta() ->
get_disposal() ->
get_position() ->
переменные:
var error :
var has_error :
var unknown_markers :
var graphic_control_label_unknown_markers :
var Graphic_Control_Label :
var Image_Separator :
var Image_Data :
var Header :
var Canvas_Width :
var Canvas_Height :
var Global_Color_Table_Flag :
var Color_Resolution :
var Sort_Flag :
var Size_of_Global_Color_Table :
var Background_Color_Index :
var Pixel_Aspect_Ratio :
var Global_Color_Table :
var Comment_Extension :
класс GraphicControlLabel - элемент массива Graphic_Control_Label в GifData
var Byte_Size :
var Delay_Time :
var Transparent_Color_Index :
var Reserved_for_Future_Use :
var Disposal_Method :
var User_Input_Flag :
var Transparent_Color_Flag :
класс ImageSeparator - элемент массива Image_Separator в GifData
var Image_Left :
var Image_Top :
var Image_Width :
var Image_Height :
var Local_Color_Table :
var Local_Color_Table_Flag :
var Interlace_Flag :
var Sort_Flag :
var Reserved_For_Future_Use :
var Size_of_Local_Color_Table :
класс ImageData - элемент массива Image_Data в GifData
var LZW_Minimum_Code_Size :
var Index_Stream :
var Code_streams :
var Tables :
var Units :
LLGif89aDecoder is a low-level tool that decodes all fields of GIF89a format files into Godot native structures.
Installation:
- Download and place gif89a.gd anywhere in your Godot project.
- Done.
To play GIF, add a script to Node2D with the following content:
extends Node2D
var gif_player : LLGif89aDecoder.GifPlayer = null
func _ready() -> void:
var data : LLGif89aDecoder.GifData = LLGif89aDecoder.read_gif_from_path("path to gif.gif")
if data.has_error : return
gif_player = data.Gif_Player
gif_player.set_canvas_item(self)Done! gif will play when the scene starts.
to read gif from buffer, replace
var data : LLGif89aDecoder.GifData = LLGif89aDecoder.read_gif_from_path("path to gif.gif")to
var f : FileAccess = FileAccess.open("path to gif.gif",FileAccess.READ)
var data : LLGif89aDecoder.GifData = LLGif89aDecoder.read_gif_from_buffer(f.get_buffer(f.get_length()))alternative minimal version play gif without GifPlayer:
#Quick start: playing gif with LLGif89aDecoder (godot 4.5.1+)
extends Node2D
#frames data
var gif_delta : PackedFloat64Array = []
var gif_image : Array[ImageTexture] = []
var gif_position : PackedVector2Array = []
var gif_disposal : PackedByteArray = []
var gif_full_size : Vector2i = Vector2i(2,2)
var gif_background_color : Color = Color(1,1,1,0)
var time : float = 0.0
var full_time : float = 0.0
func _ready() -> void:
var data : LLGif89aDecoder.GifData = LLGif89aDecoder.read_gif_from_path("G:/delete/jumping_through_windows.gif")
if data.has_error : return #check for errors
gif_delta = data.get_converted_delta()
gif_image = data.get_image_textures()
gif_position = data.get_position()
gif_disposal = data.get_disposal()
gif_full_size = Vector2i(data.Canvas_Width,data.Canvas_Height)
gif_background_color = data.background_color
for i in gif_delta:
full_time += i
func _process(delta: float) -> void:
time = wrapf(time + delta,0.0,full_time)
queue_redraw()
func _draw() -> void:
var local_time : float = time
for i in gif_delta.size():
local_time -= gif_delta[i]
match gif_disposal[i]:
2: #clear to backgound
draw_rect(Rect2i(Vector2.ZERO,gif_full_size),gif_background_color)
3: #restore to previos frame
if local_time < 0.0:
draw_texture(gif_image[i],gif_position[i])
_: #0 - method does not require disposal, 1 - leave the current image and draw the next one on top, 4-7 behavior is undefined
draw_texture(gif_image[i],gif_position[i])
if local_time < 0.0 : breakClass GifPlayer - designed for simple gif playback.
Methods:
set_canvas_item(new_canvas_item :
set_speed_scale(new_speed_scale :
set_offset(new_offset :
set_rotation(new_rotation :
set_rotation_degrees(new_rotation_degress :
set_scale(new_scale :
set_transform(new_transform :
Class LLGif89aDecoder:
enum THREAD_MODE {current,auto,low_priority,high_priority}
THREAD_MODE.current - decoding is performed in the same thread that called the method.
THREAD_MODE.auto - decoding is performed using the optimal number of threads (6).
THREAD_MODE.low_priority - decoding is performed with high_priority = false. By default, 30% of threads will be used (ProjectSettings.threading/worker_pool/low_priority_thread_ratio).
THREAD_MODE.high_priority - decoding is performed with high_priority = true. This mode will use all threads. Use THREAD_MODE.high_priority only if you know what you are doing. For large GIFs, THREAD_MODE.high_priority may cause cache misses, which can result in significantly longer total processing time compared to THREAD_MODE.auto.
Arguments for the read_gif_from_path method
path :
Arguments for the read_gif_from_buffer method
buffer :
generate_gif_player :
print_comment :
Fields that are described here or here will be marked with clickable links. A brief description will also be provided here if necessary.
Class GifData - stores all gif fields:
Methods:
get_image_textures() ->
get_unconverted_delta() ->
get_converted_delta() ->
get_disposal() ->
get_position() ->
Variables:
var error :
var has_error :
var unknown_markers :
var graphic_control_label_unknown_markers :
var Graphic_Control_Label :
var Image_Separator :
var Image_Data :
var Header :
var Canvas_Width :
var Canvas_Height :
var Global_Color_Table_Flag :
var Color_Resolution :
var Sort_Flag :
var Size_of_Global_Color_Table :
var Background_Color_Index :
var Pixel_Aspect_Ratio :
var Global_Color_Table :
var Comment_Extension :
Class GraphicControlLabel - element of the Graphic_Control_Label array in GifData
var Byte_Size :
var Delay_Time :
var Transparent_Color_Index :
var Reserved_for_Future_Use :
var Disposal_Method :
var User_Input_Flag :
var Transparent_Color_Flag :
Class ImageSeparator - element of the Image_Separator array in GifData
var Image_Left :
var Image_Top :
var Image_Width :
var Image_Height :
var Local_Color_Table :
var Local_Color_Table_Flag :
var Interlace_Flag :
var Sort_Flag :
var Reserved_For_Future_Use :
var Size_of_Local_Color_Table :
Class ImageData - element of the Image_Data array in GifData
var LZW_Minimum_Code_Size :
var Index_Stream :
var Code_streams :
var Tables :
var Units :