@@ -107,19 +107,28 @@ func _poll_threads() -> void:
107107func 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
124133func _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
0 commit comments