mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-02-20 12:33:14 +00:00
Minor refactor of Export & ExportDialog to combine processed_images and durations into a single ProcessedImage class
This commit is contained in:
parent
cd2787b373
commit
cb58cf7163
2 changed files with 37 additions and 35 deletions
|
@ -30,8 +30,7 @@ var custom_exporter_generators := {}
|
|||
|
||||
var current_tab := ExportTab.IMAGE
|
||||
## All frames and their layers processed/blended into images
|
||||
var processed_images: Array[Image] = []
|
||||
var durations: PackedFloat32Array = []
|
||||
var processed_images: Array[ProcessedImage] = []
|
||||
|
||||
# Spritesheet options
|
||||
var orientation := Orientation.COLUMNS
|
||||
|
@ -58,6 +57,15 @@ var export_progress := 0.0
|
|||
@onready var gif_export_thread := Thread.new()
|
||||
|
||||
|
||||
class ProcessedImage:
|
||||
var image: Image
|
||||
var duration: float
|
||||
|
||||
func _init(_image: Image, _duration := 1.0) -> void:
|
||||
image = _image
|
||||
duration = _duration
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if gif_export_thread.is_started():
|
||||
gif_export_thread.wait_to_finish()
|
||||
|
@ -225,18 +233,17 @@ func process_spritesheet(project := Global.current_project) -> void:
|
|||
tag_origins[0] += 1
|
||||
_blend_layers(whole_image, frame, origin)
|
||||
|
||||
processed_images.append(whole_image)
|
||||
processed_images.append(ProcessedImage.new(whole_image))
|
||||
|
||||
|
||||
func process_animation(project := Global.current_project) -> void:
|
||||
processed_images.clear()
|
||||
durations.clear()
|
||||
var frames := _calculate_frames(project)
|
||||
for frame in frames:
|
||||
var image := Image.create(project.size.x, project.size.y, false, Image.FORMAT_RGBA8)
|
||||
_blend_layers(image, frame)
|
||||
processed_images.append(image)
|
||||
durations.append(frame.duration * (1.0 / project.fps))
|
||||
var duration := frame.duration * (1.0 / project.fps)
|
||||
processed_images.append(ProcessedImage.new(image, duration))
|
||||
|
||||
|
||||
func _calculate_frames(project := Global.current_project) -> Array[Frame]:
|
||||
|
@ -320,7 +327,6 @@ func export_processed_images(
|
|||
var result := true
|
||||
var details := {
|
||||
"processed_images": processed_images,
|
||||
"durations": durations,
|
||||
"export_dialog": export_dialog,
|
||||
"export_paths": export_paths,
|
||||
"project": project
|
||||
|
@ -368,19 +374,19 @@ func export_processed_images(
|
|||
if OS.has_feature("web"):
|
||||
if project.file_format == FileFormat.PNG:
|
||||
JavaScriptBridge.download_buffer(
|
||||
processed_images[i].save_png_to_buffer(),
|
||||
processed_images[i].image.save_png_to_buffer(),
|
||||
export_paths[i].get_file(),
|
||||
"image/png"
|
||||
)
|
||||
elif project.file_format == FileFormat.WEBP:
|
||||
JavaScriptBridge.download_buffer(
|
||||
processed_images[i].save_webp_to_buffer(),
|
||||
processed_images[i].image.save_webp_to_buffer(),
|
||||
export_paths[i].get_file(),
|
||||
"image/webp"
|
||||
)
|
||||
elif project.file_format == FileFormat.JPEG:
|
||||
JavaScriptBridge.download_buffer(
|
||||
processed_images[i].save_jpg_to_buffer(),
|
||||
processed_images[i].image.save_jpg_to_buffer(),
|
||||
export_paths[i].get_file(),
|
||||
"image/jpeg"
|
||||
)
|
||||
|
@ -388,11 +394,11 @@ func export_processed_images(
|
|||
else:
|
||||
var err: Error
|
||||
if project.file_format == FileFormat.PNG:
|
||||
err = processed_images[i].save_png(export_paths[i])
|
||||
err = processed_images[i].image.save_png(export_paths[i])
|
||||
elif project.file_format == FileFormat.WEBP:
|
||||
err = processed_images[i].save_webp(export_paths[i])
|
||||
err = processed_images[i].image.save_webp(export_paths[i])
|
||||
elif project.file_format == FileFormat.JPEG:
|
||||
err = processed_images[i].save_jpg(export_paths[i])
|
||||
err = processed_images[i].image.save_jpg(export_paths[i])
|
||||
if err != OK:
|
||||
Global.popup_error(
|
||||
tr("File failed to save. Error code %s (%s)") % [err, error_string(err)]
|
||||
|
@ -425,9 +431,9 @@ func export_video(export_paths: PackedStringArray) -> bool:
|
|||
for i in range(processed_images.size()):
|
||||
var temp_file_name := str(i + 1).pad_zeros(number_of_digits) + ".png"
|
||||
var temp_file_path := temp_path_real.path_join(temp_file_name)
|
||||
processed_images[i].save_png(temp_file_path)
|
||||
processed_images[i].image.save_png(temp_file_path)
|
||||
input_file.store_line("file '" + temp_file_name + "'")
|
||||
input_file.store_line("duration %s" % durations[i])
|
||||
input_file.store_line("duration %s" % processed_images[i].duration)
|
||||
input_file.close()
|
||||
var ffmpeg_execute: PackedStringArray = [
|
||||
"-y", "-f", "concat", "-i", input_file_path, export_paths[0]
|
||||
|
@ -464,8 +470,8 @@ func export_animated(args: Dictionary) -> void:
|
|||
var frames := []
|
||||
for i in range(processed_images.size()):
|
||||
var frame: AImgIOFrame = AImgIOFrame.new()
|
||||
frame.content = processed_images[i]
|
||||
frame.duration = durations[i]
|
||||
frame.content = processed_images[i].image
|
||||
frame.duration = processed_images[i].duration
|
||||
frames.push_back(frame)
|
||||
|
||||
# Export and save GIF/APNG
|
||||
|
@ -489,13 +495,12 @@ func _increase_export_progress(export_dialog: Node) -> void:
|
|||
|
||||
|
||||
func _scale_processed_images() -> void:
|
||||
var resize_f := resize / 100.0
|
||||
for processed_image in processed_images:
|
||||
if resize != 100:
|
||||
processed_image.resize(
|
||||
processed_image.get_size().x * resize / 100,
|
||||
processed_image.get_size().y * resize / 100,
|
||||
interpolation
|
||||
)
|
||||
if is_equal_approx(resize, 1.0):
|
||||
continue
|
||||
var image := processed_image.image
|
||||
image.resize(image.get_size().x * resize_f, image.get_size().y * resize_f, interpolation)
|
||||
|
||||
|
||||
func file_format_string(format_enum: int) -> String:
|
||||
|
|
|
@ -2,7 +2,7 @@ extends ConfirmationDialog
|
|||
|
||||
## Called when user resumes export after filename collision
|
||||
signal resume_export_function
|
||||
signal about_to_preview(Dictionary)
|
||||
signal about_to_preview(dict: Dictionary)
|
||||
|
||||
var preview_current_frame := 0
|
||||
var preview_frames: Array[Texture2D] = []
|
||||
|
@ -24,8 +24,7 @@ var spritesheet_exports: Array[Export.FileFormat] = [
|
|||
Export.FileFormat.PNG, Export.FileFormat.WEBP, Export.FileFormat.JPEG
|
||||
]
|
||||
|
||||
var _preview_images: Array[Image]
|
||||
var _preview_durations: PackedFloat32Array
|
||||
var _preview_images: Array[Export.ProcessedImage]
|
||||
|
||||
@onready var tabs: TabBar = $VBoxContainer/TabBar
|
||||
@onready var checker: ColorRect = $"%TransparentChecker"
|
||||
|
@ -97,19 +96,17 @@ func show_tab() -> void:
|
|||
|
||||
|
||||
func set_preview() -> void:
|
||||
_preview_images = Export.processed_images.duplicate()
|
||||
_preview_durations = Export.durations.duplicate()
|
||||
_preview_images = Export.processed_images
|
||||
var preview_data = {
|
||||
"exporter_id": Global.current_project.file_format,
|
||||
"export_tab": Export.current_tab,
|
||||
"preview_images": _preview_images,
|
||||
"durations": _preview_durations
|
||||
}
|
||||
about_to_preview.emit(preview_data)
|
||||
remove_previews()
|
||||
if _preview_images.size() == 1:
|
||||
previews.columns = 1
|
||||
add_image_preview(_preview_images[0])
|
||||
add_image_preview(_preview_images[0].image)
|
||||
else:
|
||||
if Export.is_single_file_format():
|
||||
previews.columns = 1
|
||||
|
@ -117,7 +114,7 @@ func set_preview() -> void:
|
|||
else:
|
||||
previews.columns = ceili(sqrt(_preview_images.size()))
|
||||
for i in range(_preview_images.size()):
|
||||
add_image_preview(_preview_images[i], i + 1)
|
||||
add_image_preview(_preview_images[i].image, i + 1)
|
||||
|
||||
|
||||
func add_image_preview(image: Image, canvas_number: int = -1) -> void:
|
||||
|
@ -140,7 +137,7 @@ func add_animated_preview() -> void:
|
|||
preview_frames = []
|
||||
|
||||
for processed_image in _preview_images:
|
||||
var texture := ImageTexture.create_from_image(processed_image)
|
||||
var texture := ImageTexture.create_from_image(processed_image.image)
|
||||
preview_frames.push_back(texture)
|
||||
|
||||
var container := create_preview_container()
|
||||
|
@ -152,7 +149,7 @@ func add_animated_preview() -> void:
|
|||
|
||||
previews.add_child(container)
|
||||
frame_timer.set_one_shot(true) # wait_time can't change correctly if the timer is playing
|
||||
frame_timer.wait_time = _preview_durations[preview_current_frame]
|
||||
frame_timer.wait_time = _preview_images[preview_current_frame].duration
|
||||
frame_timer.start()
|
||||
|
||||
|
||||
|
@ -239,7 +236,7 @@ func create_layer_list() -> void:
|
|||
|
||||
func update_dimensions_label() -> void:
|
||||
if _preview_images.size() > 0:
|
||||
var new_size: Vector2 = _preview_images[0].get_size() * (Export.resize / 100.0)
|
||||
var new_size: Vector2 = _preview_images[0].image.get_size() * (Export.resize / 100.0)
|
||||
dimension_label.text = str(new_size.x, "×", new_size.y)
|
||||
|
||||
|
||||
|
@ -413,7 +410,7 @@ func _on_FrameTimer_timeout() -> void:
|
|||
else:
|
||||
preview_current_frame += 1
|
||||
|
||||
frame_timer.wait_time = _preview_durations[preview_current_frame - 1]
|
||||
frame_timer.wait_time = _preview_images[preview_current_frame - 1].duration
|
||||
frame_timer.start()
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue