1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-31 07:29:49 +00:00

[Undo/Redo] Compress most of the images stored in memory

Combines e62548517f, 4f5f37a522, e22794e611, 9279a8e0ab and 2c5ece53dd from the master branch.
This commit is contained in:
Emmanouil Papadeas 2023-11-16 20:59:48 +02:00
parent 6473febe78
commit e0bd25c374
10 changed files with 86 additions and 109 deletions

View file

@ -432,10 +432,11 @@ func scale_image(width: int, height: int, interpolation: int) -> void:
for f in Global.current_project.frames:
for i in range(f.cels.size() - 1, -1, -1):
if not f.cels[i] is PixelCel:
var cel: BaseCel = f.cels[i]
if not cel is PixelCel:
continue
var sprite := Image.new()
sprite.copy_from(f.cels[i].image)
sprite.copy_from(cel.image)
if interpolation == Interpolation.SCALE3X:
var times: Vector2 = Vector2(
ceil(width / (3.0 * sprite.get_width())),
@ -454,10 +455,7 @@ func scale_image(width: int, height: int, interpolation: int) -> void:
gen.generate_image(sprite, omniscale_shader, params, Vector2(width, height))
else:
sprite.resize(width, height, interpolation)
Global.current_project.undo_redo.add_do_property(f.cels[i].image, "data", sprite.data)
Global.current_project.undo_redo.add_undo_property(
f.cels[i].image, "data", f.cels[i].image.data
)
Global.undo_redo_compress_images({cel.image: sprite.data}, {cel.image: cel.image.data})
general_undo_scale()
@ -487,8 +485,7 @@ func center(indices: Array) -> void:
var sprite := Image.new()
sprite.create(project.size.x, project.size.y, false, Image.FORMAT_RGBA8)
sprite.blend_rect(cel.image, used_rect, offset)
project.undo_redo.add_do_property(cel.image, "data", sprite.data)
project.undo_redo.add_undo_property(cel.image, "data", cel.image.data)
Global.undo_redo_compress_images({cel.image: sprite.data}, {cel.image: cel.image.data})
project.undo_redo.add_undo_method(Global, "undo_or_redo", true)
project.undo_redo.add_do_method(Global, "undo_or_redo", false)
project.undo_redo.commit_action()
@ -524,8 +521,7 @@ func crop_image() -> void:
if not cel is PixelCel:
continue
var sprite: Image = cel.image.get_rect(used_rect)
Global.current_project.undo_redo.add_do_property(cel.image, "data", sprite.data)
Global.current_project.undo_redo.add_undo_property(cel.image, "data", cel.image.data)
Global.undo_redo_compress_images({cel.image: sprite.data}, {cel.image: cel.image.data})
general_undo_scale()
@ -533,18 +529,17 @@ func crop_image() -> void:
func resize_canvas(width: int, height: int, offset_x: int, offset_y: int) -> void:
general_do_scale(width, height)
for f in Global.current_project.frames:
for c in f.cels:
if not c is PixelCel:
for cel in f.cels:
if not cel is PixelCel:
continue
var sprite := Image.new()
sprite.create(width, height, false, Image.FORMAT_RGBA8)
sprite.blend_rect(
c.image,
cel.image,
Rect2(Vector2.ZERO, Global.current_project.size),
Vector2(offset_x, offset_y)
)
Global.current_project.undo_redo.add_do_property(c.image, "data", sprite.data)
Global.current_project.undo_redo.add_undo_property(c.image, "data", c.image.data)
Global.undo_redo_compress_images({cel.image: sprite.data}, {cel.image: cel.image.data})
general_undo_scale()

View file

@ -480,7 +480,8 @@ func undo_or_redo(
"Center Frames",
"Merge Layer",
"Link Cel",
"Unlink Cel"
"Unlink Cel",
"Replaced Cel"
]
):
if layer_index > -1 and frame_index > -1:
@ -619,5 +620,44 @@ func convert_dictionary_values(dict: Dictionary) -> void:
dict[key] = str2var("Vector3" + dict[key])
func undo_redo_draw_op(image: Object, compressed_image_data: Dictionary, buffer_size: int) -> void:
image["data"]["data"] = compressed_image_data["data"].decompress(buffer_size)
func undo_redo_compress_images(redo_data: Dictionary, undo_data: Dictionary, project := current_project) -> void:
for image in redo_data:
if not image is Image:
continue
var new_image: Dictionary = redo_data[image]
var new_size := Vector2(new_image["width"], new_image["height"])
var buffer_size: int = new_image["data"].size()
var compressed_data: PoolByteArray = new_image["data"].compress()
project.undo_redo.add_do_method(
self, "undo_redo_draw_op", image, new_size, compressed_data, buffer_size
)
image.unlock()
for image in undo_data:
if not image is Image:
continue
var new_image: Dictionary = undo_data[image]
var new_size := Vector2(new_image["width"], new_image["height"])
var buffer_size: int = new_image["data"].size()
var compressed_data: PoolByteArray = new_image["data"].compress()
project.undo_redo.add_undo_method(
self, "undo_redo_draw_op", image, new_size, compressed_data, buffer_size
)
func undo_redo_draw_op(
image: Image, new_size: Vector2, compressed_image_data: PoolByteArray, buffer_size: int
) -> void:
var decompressed := compressed_image_data.decompress(buffer_size)
image.crop(new_size.x, new_size.y)
image.data["data"] = decompressed
## Used by the Move tool for undo/redo, moves all of the Images in the images array
## by diff pixels.
func undo_redo_move(diff: Vector2, images: Array) -> void:
for image in images:
var image_copy := Image.new()
image_copy.copy_from(image)
image.fill(Color(0, 0, 0, 0))
image.blit_rect(image_copy, Rect2(Vector2.ZERO, image.get_size()), diff)

View file

@ -544,8 +544,9 @@ func open_image_at_cel(image: Image, layer_index := 0, frame_index := 0) -> void
cel_image.create(project_width, project_height, false, Image.FORMAT_RGBA8)
cel_image.blit_rect(image, Rect2(Vector2.ZERO, image.get_size()), Vector2.ZERO)
var cel: PixelCel = project.frames[i].cels[layer_index]
project.undo_redo.add_do_property(cel, "image", cel_image)
project.undo_redo.add_undo_property(cel, "image", cel.image)
Global.undo_redo_compress_images(
{cel.image: cel_image.data}, {cel.image: cel.image.data}, project
)
project.undo_redo.add_do_property(project, "selected_cels", [])
project.undo_redo.add_do_method(project, "change_cel", frame_index, layer_index)

View file

@ -152,10 +152,7 @@ func _commit_undo(action: String, undo_data: Dictionary, project: Project) -> vo
var redo_data := _get_undo_data(project)
project.undos += 1
project.undo_redo.create_action(action)
for image in redo_data:
project.undo_redo.add_do_property(image, "data", redo_data[image])
for image in undo_data:
project.undo_redo.add_undo_property(image, "data", undo_data[image])
Global.undo_redo_compress_images(redo_data, undo_data, project)
project.undo_redo.add_do_method(Global, "undo_or_redo", false, -1, -1, project)
project.undo_redo.add_undo_method(Global, "undo_or_redo", true, -1, -1, project)
project.undo_redo.commit_action()

View file

@ -156,5 +156,5 @@ visible = false
[connection signal="custom_action" from="Dialogs/QuitAndSaveDialog" to="." method="_on_QuitAndSaveDialog_custom_action"]
[connection signal="popup_hide" from="Dialogs/QuitAndSaveDialog" to="." method="_can_draw_true"]
[connection signal="popup_hide" from="Dialogs/ErrorDialog" to="." method="_can_draw_true"]
[connection signal="popup_hide" from="Dialogs/BackupConfirmation" to="." method="_on_BackupConfirmation_popup_hide"]
[connection signal="popup_hide" from="Dialogs/BackupConfirmation" to="." method="_can_draw_true"]
[connection signal="popup_hide" from="Dialogs/BackupConfirmation" to="." method="_on_BackupConfirmation_popup_hide"]

View file

@ -485,11 +485,7 @@ func commit_undo(action: String, undo_data: Dictionary) -> void:
project.undos += 1
project.undo_redo.create_action(action)
for image in redo_data:
project.undo_redo.add_do_property(image, "data", redo_data[image])
image.unlock()
for image in undo_data:
project.undo_redo.add_undo_property(image, "data", undo_data[image])
Global.undo_redo_compress_images(redo_data, undo_data, project)
project.undo_redo.add_do_method(Global, "undo_or_redo", false, frame, layer)
project.undo_redo.add_undo_method(Global, "undo_or_redo", true, frame, layer)
project.undo_redo.commit_action()

View file

@ -209,21 +209,7 @@ func commit_undo() -> void:
layer = project.current_layer
project.undos += 1
for image in redo_data:
var compressed_data = redo_data[image]
var buffer_size = compressed_data["data"].size()
compressed_data["data"] = compressed_data["data"].compress()
project.undo_redo.add_do_method(
Global, "undo_redo_draw_op", image, compressed_data, buffer_size
)
image.unlock()
for image in _undo_data:
var compressed_data = _undo_data[image]
var buffer_size = compressed_data["data"].size()
compressed_data["data"] = compressed_data["data"].compress()
project.undo_redo.add_undo_method(
Global, "undo_redo_draw_op", image, compressed_data, buffer_size
)
Global.undo_redo_compress_images(redo_data, _undo_data, project)
project.undo_redo.add_do_method(Global, "undo_or_redo", false, frame, layer)
project.undo_redo.add_undo_method(Global, "undo_or_redo", true, frame, layer)
project.undo_redo.commit_action()

View file

@ -1,6 +1,5 @@
extends BaseTool
var _undo_data := {}
var _start_pos: Vector2
var _offset: Vector2
@ -42,7 +41,6 @@ func draw_start(position: Vector2) -> void:
return
_start_pos = position
_offset = position
_undo_data = _get_undo_data()
if Global.current_project.has_selection:
selection_node.transform_content_start()
_content_transformation_check = selection_node.is_moving_content
@ -83,14 +81,7 @@ func draw_end(position: Vector2) -> void:
else:
var pixel_diff: Vector2 = position - _start_pos
Global.canvas.move_preview_location = Vector2.ZERO
var images := _get_selected_draw_images()
for image in images:
var image_copy := Image.new()
image_copy.copy_from(image)
image.fill(Color(0, 0, 0, 0))
image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff)
commit_undo("Draw")
commit_undo("Draw", pixel_diff)
_start_pos = Vector2.INF
_snap_to_grid = false
@ -123,45 +114,18 @@ func _snap_position(position: Vector2) -> Vector2:
return position
func commit_undo(action: String) -> void:
var redo_data := _get_undo_data()
func commit_undo(action: String, diff: Vector2) -> void:
var project: Project = Global.current_project
var frame := -1
var layer := -1
if Global.animation_timer.is_stopped() and project.selected_cels.size() == 1:
frame = project.current_frame
layer = project.current_layer
var images := _get_selected_draw_images()
project.undos += 1
project.undo_redo.create_action(action)
for image in redo_data:
project.undo_redo.add_do_property(image, "data", redo_data[image])
image.unlock()
for image in _undo_data:
project.undo_redo.add_undo_property(image, "data", _undo_data[image])
project.undo_redo.add_do_method(Global, "undo_redo_move", diff, images)
project.undo_redo.add_do_method(Global, "undo_or_redo", false, frame, layer)
project.undo_redo.add_undo_method(Global, "undo_redo_move", -diff, images)
project.undo_redo.add_undo_method(Global, "undo_or_redo", true, frame, layer)
project.undo_redo.commit_action()
_undo_data.clear()
func _get_undo_data() -> Dictionary:
var data := {}
var project: Project = Global.current_project
var cels := [] # Array of Cels
if Global.animation_timer.is_stopped():
for cel_index in project.selected_cels:
cels.append(project.frames[cel_index[0]].cels[cel_index[1]])
else:
for frame in project.frames:
var cel: PixelCel = frame.cels[project.current_layer]
cels.append(cel)
for cel in cels:
if not cel is PixelCel:
continue
var image: Image = cel.image
image.unlock()
data[image] = image.data
image.lock()
return data

View file

@ -55,31 +55,27 @@ func _commit_undo(action: String, undo_data: Dictionary, project: Project) -> vo
var redo_data := _get_undo_data(project)
project.undos += 1
project.undo_redo.create_action(action)
Global.undo_redo_compress_images(redo_data, undo_data, project)
if redo_data.has("outline_offset"):
project.undo_redo.add_do_property(project, "selection_map", redo_data["selection_map"])
project.undo_redo.add_do_property(project, "selection_offset", redo_data["outline_offset"])
project.undo_redo.add_undo_property(project, "selection_map", undo_data["selection_map"])
project.undo_redo.add_undo_property(project, "selection_offset", undo_data["outline_offset"])
for image in redo_data:
if not image is Image:
continue
project.undo_redo.add_do_property(image, "data", redo_data[image])
image.unlock()
for image in undo_data:
if not image is Image:
continue
project.undo_redo.add_undo_property(image, "data", undo_data[image])
project.undo_redo.add_do_method(Global, "undo_or_redo", false, -1, -1, project)
project.undo_redo.add_undo_property(
project, "selection_offset", undo_data["outline_offset"]
)
project.undo_redo.add_do_method(project, "selection_map_changed")
project.undo_redo.add_undo_method(Global, "undo_or_redo", true, -1, -1, project)
project.undo_redo.add_undo_method(project, "selection_map_changed")
project.undo_redo.add_do_method(Global, "undo_or_redo", false, -1, -1, project)
project.undo_redo.add_undo_method(Global, "undo_or_redo", true, -1, -1, project)
project.undo_redo.commit_action()
func _get_undo_data(project: Project) -> Dictionary:
var affect_selection := selection_checkbox.pressed and project.has_selection
var data := {}
if affect_selection:
var bitmap_image := SelectionMap.new()
bitmap_image.copy_from(project.selection_map)
var data := {}
data["selection_map"] = bitmap_image
data["outline_offset"] = project.selection_offset
@ -87,7 +83,6 @@ func _get_undo_data(project: Project) -> Dictionary:
for image in images:
image.unlock()
data[image] = image.data
return data

View file

@ -870,8 +870,11 @@ func _on_MergeDownLayer_pressed() -> void:
project.undo_redo.add_do_property(bottom_cel, "image", bottom_image)
project.undo_redo.add_undo_property(bottom_cel, "image", bottom_cel.image)
else:
project.undo_redo.add_do_property(bottom_cel.image, "data", bottom_image.data)
project.undo_redo.add_undo_property(bottom_cel.image, "data", bottom_cel.image.data)
Global.undo_redo_compress_images(
{bottom_cel.image: bottom_image.data},
{bottom_cel.image: bottom_cel.image.data},
project
)
project.undo_redo.add_do_method(project, "remove_layers", [top_layer.index])
project.undo_redo.add_undo_method(