From ebc9eab7737ec06af85aa350bc2aa166184c1fee Mon Sep 17 00:00:00 2001 From: OverloadedOrama <35376950+OverloadedOrama@users.noreply.github.com> Date: Sat, 1 Aug 2020 04:24:11 +0300 Subject: [PATCH] Added dialog with options for desaturation Not sure if options for RGBA channels are really needed here, but I kept them from invert colors. We could remove them in the future if they are unneeded. --- src/Autoload/DrawingAlgos.gd | 26 ++-- .../Dialogs/ImageEffects/DesaturateDialog.gd | 112 ++++++++++++++++++ .../ImageEffects/DesaturateDialog.tscn | 101 ++++++++++++++++ src/UI/Dialogs/ImageEffects/ImageEffects.tscn | 5 +- .../ImageEffects/InvertColorsDialog.tscn | 2 + src/UI/TopMenuContainer.gd | 3 +- 6 files changed, 236 insertions(+), 13 deletions(-) create mode 100644 src/UI/Dialogs/ImageEffects/DesaturateDialog.gd create mode 100644 src/UI/Dialogs/ImageEffects/DesaturateDialog.tscn diff --git a/src/Autoload/DrawingAlgos.gd b/src/Autoload/DrawingAlgos.gd index 828c9e882..705bd0969 100644 --- a/src/Autoload/DrawingAlgos.gd +++ b/src/Autoload/DrawingAlgos.gd @@ -310,17 +310,21 @@ func invert_image_colors(image : Image, pixels : Array, red := true, green := tr image.set_pixelv(i, px_color) -func desaturate_image(image : Image) -> void: - Global.canvas.handle_undo("Draw") - for xx in image.get_size().x: - for yy in image.get_size().y: - var px_color = image.get_pixel(xx, yy) - if px_color.a == 0: - continue - var gray = image.get_pixel(xx, yy).v - px_color = Color(gray, gray, gray, px_color.a) - image.set_pixel(xx, yy, px_color) - Global.canvas.handle_redo("Draw") +func desaturate_image(image : Image, pixels : Array, red := true, green := true, blue := true, alpha := false) -> void: + image.lock() + for i in pixels: + var px_color := image.get_pixelv(i) + var gray = px_color.v + if red: + px_color.r = gray + if green: + px_color.g = gray + if blue: + px_color.b = gray + if alpha: + px_color.a = gray + + image.set_pixelv(i, px_color) func generate_outline(image : Image, pixels : Array, outline_color : Color, thickness : int, diagonal : bool, inside_image : bool) -> void: diff --git a/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd b/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd new file mode 100644 index 000000000..974b3adbe --- /dev/null +++ b/src/UI/Dialogs/ImageEffects/DesaturateDialog.gd @@ -0,0 +1,112 @@ +extends ConfirmationDialog + + +enum {CEL, FRAME, ALL_FRAMES, ALL_PROJECTS} + +var affect : int = CEL +var pixels := [] +var current_cel : Image +var preview_image : Image +var preview_texture : ImageTexture + +var red := true +var green := true +var blue := true +var alpha := false + +onready var preview : TextureRect = $VBoxContainer/Preview +onready var selection_checkbox = $VBoxContainer/OptionsContainer/SelectionCheckBox + + +func _ready() -> void: + current_cel = Image.new() + preview_image = Image.new() + preview_texture = ImageTexture.new() + + +func _on_FlipImageDialog_about_to_show() -> void: + current_cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image + _on_SelectionCheckBox_toggled(selection_checkbox.pressed) + + +func _on_FlipImageDialog_confirmed() -> void: + if affect == CEL: + Global.canvas.handle_undo("Draw") + DrawingAlgos.desaturate_image(current_cel, pixels, red, green, blue, alpha) + Global.canvas.handle_redo("Draw") + elif affect == FRAME: + Global.canvas.handle_undo("Draw", Global.current_project, -1) + for cel in Global.current_project.frames[Global.current_project.current_frame].cels: + DrawingAlgos.desaturate_image(cel.image, pixels, red, green, blue, alpha) + Global.canvas.handle_redo("Draw", Global.current_project, -1) + + elif affect == ALL_FRAMES: + Global.canvas.handle_undo("Draw", Global.current_project, -1, -1) + for frame in Global.current_project.frames: + for cel in frame.cels: + DrawingAlgos.desaturate_image(cel.image, pixels, red, green, blue, alpha) + Global.canvas.handle_redo("Draw", Global.current_project, -1, -1) + + elif affect == ALL_PROJECTS: + for project in Global.projects: + var _pixels := [] + if selection_checkbox.pressed: + _pixels = project.selected_pixels.duplicate() + else: + for x in project.size.x: + for y in project.size.y: + _pixels.append(Vector2(x, y)) + + Global.canvas.handle_undo("Draw", project, -1, -1) + for frame in project.frames: + for cel in frame.cels: + DrawingAlgos.desaturate_image(cel.image, _pixels, red, green, blue, alpha) + Global.canvas.handle_redo("Draw", project, -1, -1) + + +func _on_RButton_toggled(button_pressed : bool) -> void: + red = button_pressed + update_preview() + + +func _on_GButton_toggled(button_pressed : bool) -> void: + green = button_pressed + update_preview() + + +func _on_BButton_toggled(button_pressed : bool) -> void: + blue = button_pressed + update_preview() + + +func _on_AButton_toggled(button_pressed : bool) -> void: + alpha = button_pressed + update_preview() + + +func _on_SelectionCheckBox_toggled(button_pressed : bool) -> void: + pixels.clear() + if button_pressed: + pixels = Global.current_project.selected_pixels.duplicate() + else: + for x in Global.current_project.size.x: + for y in Global.current_project.size.y: + pixels.append(Vector2(x, y)) + + update_preview() + + +func _on_AffectOptionButton_item_selected(index : int) -> void: + affect = index + + +func update_preview() -> void: + preview_image.copy_from(current_cel) + DrawingAlgos.desaturate_image(preview_image, pixels, red, green, blue, alpha) + preview_image.unlock() + preview_texture.create_from_image(preview_image, 0) + preview.texture = preview_texture + + +func _on_FlipImageDialog_popup_hide() -> void: + Global.dialog_open(false) diff --git a/src/UI/Dialogs/ImageEffects/DesaturateDialog.tscn b/src/UI/Dialogs/ImageEffects/DesaturateDialog.tscn new file mode 100644 index 000000000..82ac6edc8 --- /dev/null +++ b/src/UI/Dialogs/ImageEffects/DesaturateDialog.tscn @@ -0,0 +1,101 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://src/UI/Dialogs/ImageEffects/DesaturateDialog.gd" type="Script" id=1] + +[node name="DesaturateDialog" type="ConfirmationDialog"] +margin_right = 200.0 +margin_bottom = 70.0 +window_title = "Desaturation" +resizable = true +script = ExtResource( 1 ) + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +margin_left = 8.0 +margin_top = 8.0 +margin_right = 271.0 +margin_bottom = 260.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Preview" type="TextureRect" parent="VBoxContainer"] +margin_right = 263.0 +margin_bottom = 200.0 +rect_min_size = Vector2( 200, 200 ) +expand = true +stretch_mode = 6 + +[node name="RGBAContainer" type="HBoxContainer" parent="VBoxContainer"] +margin_top = 204.0 +margin_right = 263.0 +margin_bottom = 224.0 +alignment = 1 + +[node name="RButton" type="Button" parent="VBoxContainer/RGBAContainer"] +margin_left = 83.0 +margin_right = 103.0 +margin_bottom = 20.0 +hint_tooltip = "Modify Red Channel" +mouse_default_cursor_shape = 2 +toggle_mode = true +pressed = true +text = "R" + +[node name="GButton" type="Button" parent="VBoxContainer/RGBAContainer"] +margin_left = 107.0 +margin_right = 129.0 +margin_bottom = 20.0 +hint_tooltip = "Modify Green Channel" +mouse_default_cursor_shape = 2 +toggle_mode = true +pressed = true +text = "G" + +[node name="BButton" type="Button" parent="VBoxContainer/RGBAContainer"] +margin_left = 133.0 +margin_right = 154.0 +margin_bottom = 20.0 +hint_tooltip = "Modify Blue Channel" +mouse_default_cursor_shape = 2 +toggle_mode = true +pressed = true +text = "B" + +[node name="AButton" type="Button" parent="VBoxContainer/RGBAContainer"] +margin_left = 158.0 +margin_right = 179.0 +margin_bottom = 20.0 +hint_tooltip = "Modify Alpha Channel" +mouse_default_cursor_shape = 2 +toggle_mode = true +text = "A" + +[node name="OptionsContainer" type="HBoxContainer" parent="VBoxContainer"] +margin_top = 228.0 +margin_right = 263.0 +margin_bottom = 252.0 + +[node name="SelectionCheckBox" type="CheckBox" parent="VBoxContainer/OptionsContainer"] +margin_right = 160.0 +margin_bottom = 24.0 +mouse_default_cursor_shape = 2 +pressed = true +text = "Only affect selection" + +[node name="AffectOptionButton" type="OptionButton" parent="VBoxContainer/OptionsContainer"] +margin_left = 164.0 +margin_right = 263.0 +margin_bottom = 24.0 +mouse_default_cursor_shape = 2 +text = "Current cel" +items = [ "Current cel", null, false, 0, null, "Current frame", null, false, 1, null, "All frames", null, false, 2, null, "All projects", null, false, 3, null ] +selected = 0 +[connection signal="about_to_show" from="." to="." method="_on_FlipImageDialog_about_to_show"] +[connection signal="confirmed" from="." to="." method="_on_FlipImageDialog_confirmed"] +[connection signal="popup_hide" from="." to="." method="_on_FlipImageDialog_popup_hide"] +[connection signal="toggled" from="VBoxContainer/RGBAContainer/RButton" to="." method="_on_RButton_toggled"] +[connection signal="toggled" from="VBoxContainer/RGBAContainer/GButton" to="." method="_on_GButton_toggled"] +[connection signal="toggled" from="VBoxContainer/RGBAContainer/BButton" to="." method="_on_BButton_toggled"] +[connection signal="toggled" from="VBoxContainer/RGBAContainer/AButton" to="." method="_on_AButton_toggled"] +[connection signal="toggled" from="VBoxContainer/OptionsContainer/SelectionCheckBox" to="." method="_on_SelectionCheckBox_toggled"] +[connection signal="item_selected" from="VBoxContainer/OptionsContainer/AffectOptionButton" to="." method="_on_AffectOptionButton_item_selected"] diff --git a/src/UI/Dialogs/ImageEffects/ImageEffects.tscn b/src/UI/Dialogs/ImageEffects/ImageEffects.tscn index c4a0d8380..1ee6d1651 100644 --- a/src/UI/Dialogs/ImageEffects/ImageEffects.tscn +++ b/src/UI/Dialogs/ImageEffects/ImageEffects.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=10 format=2] +[gd_scene load_steps=11 format=2] [ext_resource path="res://src/UI/Dialogs/ImageEffects/FlipImageDialog.tscn" type="PackedScene" id=1] [ext_resource path="res://src/UI/Dialogs/ImageEffects/InvertColorsDialog.tscn" type="PackedScene" id=2] +[ext_resource path="res://src/UI/Dialogs/ImageEffects/DesaturateDialog.tscn" type="PackedScene" id=3] [ext_resource path="res://src/UI/Dialogs/ImageEffects/ResizeCanvas.tscn" type="PackedScene" id=8] [ext_resource path="res://src/UI/Dialogs/ImageEffects/RotateImage.tscn" type="PackedScene" id=9] [ext_resource path="res://src/UI/Dialogs/ImageEffects/ShaderEffect.tscn" type="PackedScene" id=10] @@ -31,6 +32,8 @@ margin_bottom = 300.0 [node name="InvertColorsDialog" parent="." instance=ExtResource( 2 )] +[node name="DesaturateDialog" parent="." instance=ExtResource( 3 )] + [node name="OutlineDialog" parent="." instance=ExtResource( 13 )] margin_right = 217.0 margin_bottom = 106.0 diff --git a/src/UI/Dialogs/ImageEffects/InvertColorsDialog.tscn b/src/UI/Dialogs/ImageEffects/InvertColorsDialog.tscn index 2aa30b7af..337e76c36 100644 --- a/src/UI/Dialogs/ImageEffects/InvertColorsDialog.tscn +++ b/src/UI/Dialogs/ImageEffects/InvertColorsDialog.tscn @@ -5,6 +5,8 @@ [node name="InvertColorsDialog" type="ConfirmationDialog"] margin_right = 200.0 margin_bottom = 70.0 +window_title = "Invert Colors" +resizable = true script = ExtResource( 1 ) [node name="VBoxContainer" type="VBoxContainer" parent="."] diff --git a/src/UI/TopMenuContainer.gd b/src/UI/TopMenuContainer.gd index 752de4e1a..62c0f344d 100644 --- a/src/UI/TopMenuContainer.gd +++ b/src/UI/TopMenuContainer.gd @@ -322,7 +322,8 @@ func image_menu_id_pressed(id : int) -> void: Global.dialog_open(true) 6: # Desaturation - DrawingAlgos.desaturate_image(image) + Global.control.get_node("Dialogs/ImageEffects/DesaturateDialog").popup_centered() + Global.dialog_open(true) 7: # Outline show_add_outline_popup()