Skip to content

Commit d8438c3

Browse files
committed
Make image cropping run on a different thread, make images clickable
Additionally store the rotation count as an integer
1 parent b419356 commit d8438c3

4 files changed

Lines changed: 71 additions & 20 deletions

File tree

components/PreviewContainer.tscn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ base_font = ExtResource("3_kats2")
2222
custom_minimum_size = Vector2(0, 80)
2323
offset_right = 80.0
2424
offset_bottom = 80.0
25+
mouse_default_cursor_shape = 2
2526
theme_override_styles/panel = SubResource("StyleBoxFlat_7sarn")
2627
script = ExtResource("1_7r3w4")
2728

scripts/Application.gd

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,28 @@ func _poll_threads() -> void:
107107
func threaded_load_image(path: String, callback: Callable) -> void:
108108

109109
var worktask := ImageThreadWorkerTask.new(callback, path)
110+
var worker := select_worker()
111+
worker.add_item_to_queue(worktask)
112+
113+
func threaded_crop_image(image: Image, size: Rect2i, callback: Callable) -> void:
110114

111-
# FInd a non working thread
115+
var worktask := ImageThreadWorkerTask.new(callback, "", ImageThreadWorkerTask.WORKER_TASKS.CROP, {
116+
"image": image,
117+
"size": size,
118+
"crop_size": crop_to_size
119+
})
120+
var worker := select_worker()
121+
worker.add_item_to_queue(worktask)
122+
123+
func select_worker() -> ImageThreadWorker:
124+
# Find a non working thread
112125

113126
for worker in thread_workers:
114127
if worker.current_work_item == null:
115-
worker.add_item_to_queue(worktask)
116-
return
128+
return worker
117129

118130
# If we have no free worker sample a random one where we assign the work
119-
120-
var worker : ImageThreadWorker = thread_workers.pick_random()
121-
worker.add_item_to_queue(worktask)
122-
131+
return thread_workers.pick_random()
123132

124133
func _entry_path_changed() -> void:
125134
clear()
@@ -190,9 +199,14 @@ class ImageThreadWorker extends Resource:
190199
# If we are currently working on an item, check if we have finished that, if so clear it
191200
if current_work_item != null:
192201
if !thread.is_alive():
193-
var image := thread.wait_to_finish() as ImageTexture
194-
195-
current_work_item.callback.call(image)
202+
203+
match current_work_item.task:
204+
ImageThreadWorkerTask.WORKER_TASKS.LOAD:
205+
var image := thread.wait_to_finish() as ImageTexture
206+
current_work_item.callback.call(image)
207+
ImageThreadWorkerTask.WORKER_TASKS.CROP:
208+
var image := thread.wait_to_finish() as Image
209+
current_work_item.callback.call(image)
196210

197211
current_work_item = null
198212
check_for_work()
@@ -202,7 +216,16 @@ class ImageThreadWorker extends Resource:
202216
current_work_item = working_queue.pop_back() as ImageThreadWorkerTask
203217
thread = Thread.new()
204218

205-
thread.start(load_image_texture.bind(current_work_item.path))
219+
match current_work_item.task:
220+
ImageThreadWorkerTask.WORKER_TASKS.LOAD:
221+
thread.start(load_image_texture.bind(current_work_item.path))
222+
223+
ImageThreadWorkerTask.WORKER_TASKS.CROP:
224+
thread.start(crop_image.bind(
225+
current_work_item.data_playload["image"],
226+
current_work_item.data_playload["size"],
227+
current_work_item.data_playload["crop_size"],
228+
))
206229

207230

208231
func load_image_texture(path: String) -> ImageTexture:
@@ -214,3 +237,16 @@ class ImageThreadWorker extends Resource:
214237
return null
215238

216239
return ImageTexture.create_from_image(loaded_image)
240+
241+
func crop_image(image: Image, rect: Rect2i, size: Vector2i) -> Image:
242+
243+
if image == null:
244+
return null
245+
246+
# Get the region of the image we actually want
247+
var new_image := image.get_region(rect)
248+
249+
# Now we resize that target region into the crop size we actually want
250+
new_image.resize(size.x, size.y, Image.INTERPOLATE_LANCZOS)
251+
252+
return new_image

scripts/PreviewContainer.gd

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ func update_outline() -> void:#
5959

6060
func set_texture() -> void:
6161

62+
update_outline()
63+
6264
if image_reference == null:
6365
return
6466

@@ -70,6 +72,14 @@ func set_texture() -> void:
7072
else:
7173
texture.texture = preload("res://assets/icons/Image.svg")
7274

75+
func _gui_input(event: InputEvent) -> void:
76+
77+
if image_reference == null:
78+
return
79+
80+
if event is InputEventMouseButton:
81+
if event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
82+
Application.current_active_index = image_reference.index
7383

7484
func load_image() -> void:
7585

scripts/ProcessedImage.gd

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var original_texture : Texture2D = null
1616
var preview_texture : Texture2D = null
1717

1818
var index: int = 0
19+
var total_rotations: int = 0
1920

2021
var is_loading_image: bool = false
2122

@@ -52,6 +53,8 @@ func rotate(direction: int) -> void:
5253
if original_texture == null:
5354
return
5455

56+
total_rotations -= direction * 2 - 1
57+
5558
var new_image = original_texture.get_image()
5659
new_image.rotate_90(direction)
5760

@@ -68,22 +71,23 @@ func unload_image() -> bool:
6871

6972
return false
7073

71-
func export_image(position: Rect2i) -> bool:
74+
func export_image(position: Rect2i) -> void:
7275

7376
exported_section = position
7477

7578
# We now have our image section, where we extract a new image
7679
if original_texture != null:
77-
var new_image := original_texture.get_image().get_region(position)
7880

79-
# Now we resize that target region into the crop size we actually want
80-
new_image.resize(Application.crop_to_size.x, Application.crop_to_size.y, Image.INTERPOLATE_LANCZOS)
81+
Application.threaded_crop_image(
82+
original_texture.get_image(),
83+
position,
84+
func(image: Image):
85+
preview_texture = ImageTexture.create_from_image(image)
86+
was_already_exported = true
87+
was_exported.emit()
88+
)
89+
8190

82-
preview_texture = ImageTexture.create_from_image(new_image)
83-
84-
was_already_exported = true
85-
was_exported.emit()
86-
return false
8791

8892
func get_file_name() -> String:
8993
return source_path.get_file()

0 commit comments

Comments
 (0)