1
0
Fork 0
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:
Emmanouil Papadeas 2024-03-07 02:10:21 +02:00
parent cd2787b373
commit cb58cf7163
2 changed files with 37 additions and 35 deletions

View file

@ -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:

View file

@ -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()