shinestacker 0.5.0__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of shinestacker might be problematic. Click here for more details.

Files changed (57) hide show
  1. shinestacker/_version.py +1 -1
  2. shinestacker/algorithms/align.py +4 -12
  3. shinestacker/algorithms/balance.py +11 -9
  4. shinestacker/algorithms/depth_map.py +0 -30
  5. shinestacker/algorithms/utils.py +10 -0
  6. shinestacker/algorithms/vignetting.py +116 -70
  7. shinestacker/app/about_dialog.py +37 -16
  8. shinestacker/app/gui_utils.py +1 -1
  9. shinestacker/app/help_menu.py +1 -1
  10. shinestacker/app/main.py +2 -2
  11. shinestacker/app/project.py +2 -2
  12. shinestacker/config/constants.py +4 -1
  13. shinestacker/config/gui_constants.py +3 -4
  14. shinestacker/gui/action_config.py +5 -561
  15. shinestacker/gui/action_config_dialog.py +567 -0
  16. shinestacker/gui/base_form_dialog.py +18 -0
  17. shinestacker/gui/colors.py +5 -6
  18. shinestacker/gui/gui_logging.py +0 -1
  19. shinestacker/gui/gui_run.py +54 -106
  20. shinestacker/gui/ico/shinestacker.icns +0 -0
  21. shinestacker/gui/ico/shinestacker.ico +0 -0
  22. shinestacker/gui/ico/shinestacker.png +0 -0
  23. shinestacker/gui/ico/shinestacker.svg +60 -0
  24. shinestacker/gui/main_window.py +275 -371
  25. shinestacker/gui/menu_manager.py +236 -0
  26. shinestacker/gui/new_project.py +75 -20
  27. shinestacker/gui/project_converter.py +6 -6
  28. shinestacker/gui/project_editor.py +248 -165
  29. shinestacker/gui/project_model.py +2 -7
  30. shinestacker/gui/tab_widget.py +81 -0
  31. shinestacker/gui/time_progress_bar.py +95 -0
  32. shinestacker/retouch/base_filter.py +173 -40
  33. shinestacker/retouch/brush_preview.py +0 -10
  34. shinestacker/retouch/brush_tool.py +2 -5
  35. shinestacker/retouch/denoise_filter.py +5 -44
  36. shinestacker/retouch/exif_data.py +10 -13
  37. shinestacker/retouch/file_loader.py +1 -1
  38. shinestacker/retouch/filter_manager.py +1 -4
  39. shinestacker/retouch/image_editor_ui.py +318 -40
  40. shinestacker/retouch/image_viewer.py +34 -11
  41. shinestacker/retouch/io_gui_handler.py +34 -30
  42. shinestacker/retouch/layer_collection.py +2 -0
  43. shinestacker/retouch/shortcuts_help.py +12 -0
  44. shinestacker/retouch/unsharp_mask_filter.py +10 -10
  45. shinestacker/retouch/vignetting_filter.py +69 -0
  46. shinestacker/retouch/white_balance_filter.py +46 -14
  47. {shinestacker-0.5.0.dist-info → shinestacker-1.0.0.dist-info}/METADATA +14 -2
  48. shinestacker-1.0.0.dist-info/RECORD +90 -0
  49. shinestacker/app/app_config.py +0 -22
  50. shinestacker/gui/actions_window.py +0 -266
  51. shinestacker/retouch/image_editor.py +0 -197
  52. shinestacker/retouch/image_filters.py +0 -69
  53. shinestacker-0.5.0.dist-info/RECORD +0 -87
  54. {shinestacker-0.5.0.dist-info → shinestacker-1.0.0.dist-info}/WHEEL +0 -0
  55. {shinestacker-0.5.0.dist-info → shinestacker-1.0.0.dist-info}/entry_points.txt +0 -0
  56. {shinestacker-0.5.0.dist-info → shinestacker-1.0.0.dist-info}/licenses/LICENSE +0 -0
  57. {shinestacker-0.5.0.dist-info → shinestacker-1.0.0.dist-info}/top_level.txt +0 -0
@@ -1,197 +0,0 @@
1
- # pylint: disable=C0114, C0115, C0116, E0611, R0902
2
- from PySide6.QtWidgets import QMainWindow, QMessageBox
3
- from .. config.constants import constants
4
- from .undo_manager import UndoManager
5
- from .layer_collection import LayerCollection
6
- from .io_gui_handler import IOGuiHandler
7
- from .display_manager import DisplayManager
8
- from .brush_tool import BrushTool
9
- from .layer_collection import LayerCollectionHandler
10
-
11
-
12
- class ImageEditor(QMainWindow, LayerCollectionHandler):
13
- def __init__(self):
14
- QMainWindow.__init__(self)
15
- LayerCollectionHandler.__init__(self, LayerCollection())
16
- self.undo_manager = UndoManager()
17
- self.undo_action = None
18
- self.redo_action = None
19
- self.undo_manager.stack_changed.connect(self.update_undo_redo_actions)
20
- self.io_gui_handler = None
21
- self.display_manager = None
22
- self.brush_tool = BrushTool()
23
- self.modified = False
24
- self.installEventFilter(self)
25
- self.mask_layer = None
26
-
27
- def setup_ui(self):
28
- self.display_manager = DisplayManager(
29
- self.layer_collection, self.image_viewer,
30
- self.master_thumbnail_label, self.thumbnail_list, parent=self)
31
- self.io_gui_handler = IOGuiHandler(self.layer_collection, self.undo_manager, parent=self)
32
- self.display_manager.status_message_requested.connect(self.show_status_message)
33
- self.display_manager.cursor_preview_state_changed.connect(
34
- lambda state: setattr(self.image_viewer, 'allow_cursor_preview', state))
35
- self.io_gui_handler.status_message_requested.connect(self.show_status_message)
36
- self.io_gui_handler.update_title_requested.connect(self.update_title)
37
- self.brush_tool.setup_ui(self.brush, self.brush_preview, self.image_viewer,
38
- self.brush_size_slider, self.hardness_slider, self.opacity_slider,
39
- self.flow_slider)
40
- self.image_viewer.brush = self.brush_tool.brush
41
- self.brush_tool.update_brush_thumb()
42
- self.io_gui_handler.setup_ui(self.display_manager, self.image_viewer)
43
- self.image_viewer.display_manager = self.display_manager
44
-
45
- def show_status_message(self, message):
46
- self.statusBar().showMessage(message)
47
-
48
- # pylint: disable=C0103
49
- def keyPressEvent(self, event):
50
- if self.image_viewer.empty:
51
- return
52
- if event.text() == '[':
53
- self.brush_tool.decrease_brush_size()
54
- return
55
- if event.text() == ']':
56
- self.brush_tool.increase_brush_size()
57
- return
58
- if event.text() == '{':
59
- self.brush_tool.decrease_brush_hardness()
60
- return
61
- if event.text() == '}':
62
- self.brush_tool.increase_brush_hardness()
63
- return
64
- super().keyPressEvent(event)
65
- # pylint: enable=C0103
66
-
67
- def check_unsaved_changes(self) -> bool:
68
- if self.modified:
69
- reply = QMessageBox.question(
70
- self, "Unsaved Changes",
71
- "The image stack has unsaved changes. Do you want to continue?",
72
- QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel
73
- )
74
- if reply == QMessageBox.Save:
75
- self.save_file()
76
- return True
77
- if reply == QMessageBox.Discard:
78
- return True
79
- return False
80
- return True
81
-
82
- def sort_layers(self, order):
83
- self.sort_layers(order)
84
- self.display_manager.update_thumbnails()
85
- self.change_layer(self.current_layer())
86
-
87
- def update_title(self):
88
- title = constants.APP_TITLE
89
- if self.io_gui_handler is not None:
90
- path = self.io_gui_handler.current_file_path()
91
- if path != '':
92
- title += f" - {path.split('/')[-1]}"
93
- if self.modified:
94
- title += " *"
95
- self.window().setWindowTitle(title)
96
-
97
- def mark_as_modified(self):
98
- self.modified = True
99
- self.save_actions_set_enabled(True)
100
- self.update_title()
101
-
102
- def change_layer(self, layer_idx):
103
- if 0 <= layer_idx < self.number_of_layers():
104
- view_state = self.image_viewer.get_view_state()
105
- self.set_current_layer_idx(layer_idx)
106
- self.display_manager.display_current_view()
107
- self.image_viewer.set_view_state(view_state)
108
- self.thumbnail_list.setCurrentRow(layer_idx)
109
- self.thumbnail_list.setFocus()
110
- self.image_viewer.update_brush_cursor()
111
- self.image_viewer.setFocus()
112
-
113
- def prev_layer(self):
114
- if self.layer_stack() is not None:
115
- new_idx = max(0, self.current_layer_idx() - 1)
116
- if new_idx != self.current_layer_idx():
117
- self.change_layer(new_idx)
118
- self.display_manager.highlight_thumbnail(new_idx)
119
-
120
- def next_layer(self):
121
- if self.layer_stack() is not None:
122
- new_idx = min(self.number_of_layers() - 1, self.current_layer_idx() + 1)
123
- if new_idx != self.current_layer_idx():
124
- self.change_layer(new_idx)
125
- self.display_manager.highlight_thumbnail(new_idx)
126
-
127
- def copy_layer_to_master(self):
128
- if self.layer_stack() is None or self.master_layer() is None:
129
- return
130
- reply = QMessageBox.question(
131
- self,
132
- "Confirm Copy",
133
- "Warning: the current master layer will be erased\n\nDo you want to continue?",
134
- QMessageBox.Yes | QMessageBox.No,
135
- QMessageBox.No
136
- )
137
- if reply == QMessageBox.Yes:
138
- self.set_master_layer(self.current_layer().copy())
139
- self.master_layer().setflags(write=True)
140
- self.display_manager.display_current_view()
141
- self.display_manager.update_thumbnails()
142
- self.mark_as_modified()
143
- self.statusBar().showMessage(f"Copied layer {self.current_layer_idx() + 1} to master")
144
-
145
- def copy_brush_area_to_master(self, view_pos):
146
- if self.layer_stack() is None or self.number_of_layers() == 0 \
147
- or not self.display_manager.allow_cursor_preview():
148
- return
149
- area = self.brush_tool.apply_brush_operation(
150
- self.master_layer_copy(),
151
- self.current_layer(),
152
- self.master_layer(), self.mask_layer,
153
- view_pos, self.image_viewer)
154
- self.undo_manager.extend_undo_area(*area)
155
-
156
- def begin_copy_brush_area(self, pos):
157
- if self.display_manager.allow_cursor_preview():
158
- self.mask_layer = self.io_gui_handler.blank_layer.copy()
159
- self.copy_master_layer()
160
- self.undo_manager.reset_undo_area()
161
- self.copy_brush_area_to_master(pos)
162
- self.display_manager.needs_update = True
163
- if not self.display_manager.update_timer.isActive():
164
- self.display_manager.update_timer.start()
165
- self.mark_as_modified()
166
-
167
- def continue_copy_brush_area(self, pos):
168
- if self.display_manager.allow_cursor_preview():
169
- self.copy_brush_area_to_master(pos)
170
- self.display_manager.needs_update = True
171
- if not self.display_manager.update_timer.isActive():
172
- self.display_manager.update_timer.start()
173
- self.mark_as_modified()
174
-
175
- def end_copy_brush_area(self):
176
- if self.display_manager.update_timer.isActive():
177
- self.display_manager.display_master_layer()
178
- self.display_manager.update_master_thumbnail()
179
- self.undo_manager.save_undo_state(self.master_layer_copy(), 'Brush Stroke')
180
- self.display_manager.update_timer.stop()
181
- self.mark_as_modified()
182
-
183
- def update_undo_redo_actions(self, has_undo, undo_desc, has_redo, redo_desc):
184
- if self.undo_action:
185
- if has_undo:
186
- self.undo_action.setText(f"Undo {undo_desc}")
187
- self.undo_action.setEnabled(True)
188
- else:
189
- self.undo_action.setText("Undo")
190
- self.undo_action.setEnabled(False)
191
- if self.redo_action:
192
- if has_redo:
193
- self.redo_action.setText(f"Redo {redo_desc}")
194
- self.redo_action.setEnabled(True)
195
- else:
196
- self.redo_action.setText("Redo")
197
- self.redo_action.setEnabled(False)
@@ -1,69 +0,0 @@
1
- # pylint: disable=C0114, C0115, C0116, R0914
2
- import numpy as np
3
- from .image_editor import ImageEditor
4
- from .filter_manager import FilterManager
5
- from .denoise_filter import DenoiseFilter
6
- from .unsharp_mask_filter import UnsharpMaskFilter
7
- from .white_balance_filter import WhiteBalanceFilter
8
-
9
-
10
- class ImageFilters(ImageEditor):
11
- def __init__(self):
12
- super().__init__()
13
- self.filter_manager = FilterManager(self)
14
- self.filter_manager.register_filter("denoise", DenoiseFilter)
15
- self.filter_manager.register_filter("unsharp_mask", UnsharpMaskFilter)
16
- self.filter_manager.register_filter("white_balance", WhiteBalanceFilter)
17
-
18
- def denoise_filter(self):
19
- self.filter_manager.apply("denoise")
20
-
21
- def unsharp_mask(self):
22
- self.filter_manager.apply("unsharp_mask")
23
-
24
- def white_balance(self, init_val=None):
25
- self.filter_manager.apply("white_balance", init_val=init_val or (128, 128, 128))
26
-
27
- def connect_preview_toggle(self, preview_check, do_preview, restore_original):
28
- def on_toggled(checked):
29
- if checked:
30
- do_preview()
31
- else:
32
- restore_original()
33
- preview_check.toggled.connect(on_toggled)
34
-
35
- def get_pixel_color_at(self, pos, radius=None):
36
- item_pos = self.image_viewer.position_on_image(pos)
37
- x = int(item_pos.x())
38
- y = int(item_pos.y())
39
- master_layer = self.master_layer()
40
- if (0 <= x < self.master_layer().shape[1]) and \
41
- (0 <= y < self.master_layer().shape[0]):
42
- if radius is None:
43
- radius = int(self.brush.size)
44
- if radius > 0:
45
- y_indices, x_indices = np.ogrid[-radius:radius + 1, -radius:radius + 1]
46
- mask = x_indices**2 + y_indices**2 <= radius**2
47
- x0 = max(0, x - radius)
48
- x1 = min(master_layer.shape[1], x + radius + 1)
49
- y0 = max(0, y - radius)
50
- y1 = min(master_layer.shape[0], y + radius + 1)
51
- mask = mask[radius - (y - y0): radius + (y1 - y),
52
- radius - (x - x0): radius + (x1 - x)]
53
- region = master_layer[y0:y1, x0:x1]
54
- if region.size == 0:
55
- pixel = master_layer[y, x]
56
- else:
57
- if region.ndim == 3:
58
- pixel = [region[:, :, c][mask].mean() for c in range(region.shape[2])]
59
- else:
60
- pixel = region[mask].mean()
61
- else:
62
- pixel = self.master_layer()[y, x]
63
- if np.isscalar(pixel):
64
- pixel = [pixel, pixel, pixel]
65
- pixel = [np.float32(x) for x in pixel]
66
- if master_layer.dtype == np.uint16:
67
- pixel = [x / 256.0 for x in pixel]
68
- return tuple(int(v) for v in pixel)
69
- return (0, 0, 0)
@@ -1,87 +0,0 @@
1
- shinestacker/__init__.py,sha256=uq2fjAw2z_6TpH3mOcWFZ98GoEPRsNhTAK8N0MMm_e8,448
2
- shinestacker/_version.py,sha256=LyVsN6QRbZCjxbel-HtG6unyJHf29KfzURL0WnqwB_I,21
3
- shinestacker/algorithms/__init__.py,sha256=c4kRrdTLlVI70Q16XkI1RSmz5MD7npDqIpO_02jTG6g,747
4
- shinestacker/algorithms/align.py,sha256=FKGcDrp20jubY-LWA1OBqO-V781AoP8jCLH5xZm9nhk,17902
5
- shinestacker/algorithms/balance.py,sha256=y68L5h8yuIuGZI3g5Zhj-jLXXOPsxHVGEhNTbCc2tlI,16518
6
- shinestacker/algorithms/base_stack_algo.py,sha256=AFV2QkcFNaTcnISpsWHuAVy2De9hhaPcBNjE1O0h50I,1430
7
- shinestacker/algorithms/denoise.py,sha256=GL3Z4_6MHxSa7Wo4ZzQECZS87tHBFqO0sIVF_jPuYQU,426
8
- shinestacker/algorithms/depth_map.py,sha256=b88GqbRXEU3wCXBxMcStlgZ4sFJicoiZfJMD30Z4b98,7364
9
- shinestacker/algorithms/exif.py,sha256=gY9s6Cd4g4swo5qEjSbzuVIvl1GImCYu6ytOO9WrV0I,9435
10
- shinestacker/algorithms/multilayer.py,sha256=5JA6TW8oO_R3mu6cOvPno9by4md8q5sXUb8ZfsRRpmY,9259
11
- shinestacker/algorithms/noise_detection.py,sha256=CDnN8pglxufY5Y-dT3mVooD4zPySdSq9CMgtDGMXBnA,8970
12
- shinestacker/algorithms/pyramid.py,sha256=_Pk19lRQ21b3W3aHQ6DgAe9VVOfbsi2a9jrynF0qFVw,8610
13
- shinestacker/algorithms/sharpen.py,sha256=h7PMJBYxucg194Usp_6pvItPUMFYbT-ebAc_-7XBFUw,949
14
- shinestacker/algorithms/stack.py,sha256=FCU89Of-s6C_DuMleG06c8V6fnIm9MFInvkkKtTsGBo,4906
15
- shinestacker/algorithms/stack_framework.py,sha256=frw7sbc9qOfVBYP3ZOFZEaIn9O27Wms8j_mxSW79uI0,12460
16
- shinestacker/algorithms/utils.py,sha256=VLm6eZmcAk2QPvomT4d1q56laJSYfbCQmiwI2Rmuu_s,2171
17
- shinestacker/algorithms/vignetting.py,sha256=wFwi20ob1O3Memav1XQrtrOHgOtKRiK1RV4E-ex69r8,7470
18
- shinestacker/algorithms/white_balance.py,sha256=PMKsBtxOSn5aRr_Gkx1StHS4eN6kBN2EhNnhg4UG24g,501
19
- shinestacker/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- shinestacker/app/about_dialog.py,sha256=Y_gt28U3OPkKSkDdlA4kN1GCM6zkB-QJ5-c2qdeyG1Y,3321
21
- shinestacker/app/app_config.py,sha256=eTIRxp0t7Wic46jMTe_oY3kz7ktZbdM43C3bjshVDKg,494
22
- shinestacker/app/gui_utils.py,sha256=ptbUKjv5atbx5vW912_j8BVmDZpovAqZDEC48d0R2vA,2331
23
- shinestacker/app/help_menu.py,sha256=UOlabEY_EKV2Q1BoiU2JAM1udSSBAwXlL7d58bqxKe0,516
24
- shinestacker/app/main.py,sha256=tUb9aatktRJ1_oXSR3WPRubp7GDt-77mIjsHR7-0euE,6436
25
- shinestacker/app/open_frames.py,sha256=bsu32iJSYJQLe_tQQbvAU5DuMDVX6MRuNdE7B5lojZc,1488
26
- shinestacker/app/project.py,sha256=ir98-zogYmvx2QYvFbAaBUqLL03qWYkoMOIvLvmQy_w,2736
27
- shinestacker/app/retouch.py,sha256=ZQ-nRKnHo6xurcP34RNqaAWkmuGBjJ5jE05hTQ_ycis,2482
28
- shinestacker/config/__init__.py,sha256=aXxi-LmAvXd0daIFrVnTHE5OCaYeK1uf1BKMr7oaXQs,197
29
- shinestacker/config/config.py,sha256=eBko2D3ADhLTIm9X6hB_a_WsIjwgfE-qmBVkhP1XSvc,1636
30
- shinestacker/config/constants.py,sha256=MeZ15b7xIYJoN6EeiuR_OKi4sP-7_E7OtzrETzIowZI,5976
31
- shinestacker/config/gui_constants.py,sha256=XnjA65a1anlFXLm1zMP01Z8nZRBWX0D35FVxKnW2pJg,2568
32
- shinestacker/core/__init__.py,sha256=IUEIx6SQ3DygDEHN3_E6uKpHjHtUa4a_U_1dLd_8yEU,484
33
- shinestacker/core/colors.py,sha256=kr_tJA1iRsdck2JaYDb2lS-codZ4Ty9gdu3kHfiWvuM,1340
34
- shinestacker/core/core_utils.py,sha256=ulJhzen5McAb5n6wWNA_KB4U_PdTEr-H2TCQkVKUaOw,1421
35
- shinestacker/core/exceptions.py,sha256=2-noG-ORAGdvDhL8jBQFs0xxZS4fI6UIkMqrWekgk2c,1618
36
- shinestacker/core/framework.py,sha256=zCnJuQrHNpwEgJW23_BgS7iQrLolRWTAMB1oRp_a7Kk,7447
37
- shinestacker/core/logging.py,sha256=9SuSSy9Usbh7zqmLYMqkmy-VBkOJW000lwqAR0XQs30,3067
38
- shinestacker/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- shinestacker/gui/action_config.py,sha256=zWzTVkySEYfODJ620wQk6B2dr1C-YSxtDicJ0XXrU_M,48955
40
- shinestacker/gui/actions_window.py,sha256=wJ_s_acXlftwOgnttT5TWVr3dq451TLL-98dmmPYAJ4,12326
41
- shinestacker/gui/colors.py,sha256=zgLRcC3fAzklx7zzyjLEsMX2i64YTxGUmQM2woYBZuw,1344
42
- shinestacker/gui/gui_images.py,sha256=e0KAXSPruZoRHrajfdlmOKBYoRJJQBDan1jgs7YFltY,5678
43
- shinestacker/gui/gui_logging.py,sha256=ciuwZU-_5TicPpjC83iZmcwuDWiBO17onYJRGyF0FaY,8227
44
- shinestacker/gui/gui_run.py,sha256=n0OaPZn9C4SVpopMNKUpksMwV27xT0TGFn1inhmCFIk,16230
45
- shinestacker/gui/main_window.py,sha256=0CDi_uHHGiz1_htLNZ_iApywEaEYkNXnTcGfvOcgk_s,28817
46
- shinestacker/gui/new_project.py,sha256=GSqYfonv-jdOEb4veXU6LxiDsAevr1TulzT0vsVazAk,8342
47
- shinestacker/gui/project_converter.py,sha256=zZfXZg2h-PHh2Prr450B1UFADbZPzMBVkYhcpZkqPuk,7370
48
- shinestacker/gui/project_editor.py,sha256=zwmj7PFs7X06GY4tkoDBcOL4Tl0IGo4Mf13n2qGwaJY,22245
49
- shinestacker/gui/project_model.py,sha256=89L0IDSAqRK2mvU1EVIrcsJas8CU-aTzUIjdL1Cv0mw,4421
50
- shinestacker/gui/select_path_widget.py,sha256=OfQImOmkzbvl5BBshmb7ePWrSGDJQ8VvyaAOypHAGd4,1023
51
- shinestacker/gui/ico/focus_stack_bkg.png,sha256=Q86TgqvKEi_IzKI8m6aZB2a3T40UkDtexf2PdeBM9XE,163151
52
- shinestacker/gui/ico/shinestacker.icns,sha256=m_6WQBx8sE9jQKwIRa_B5oa7_VcNn6e2TyijeQXPjwM,337563
53
- shinestacker/gui/ico/shinestacker.ico,sha256=yO0NaBWA0uFov_GqHuHQbymoqLtQKt5DPWpGGmRKie0,186277
54
- shinestacker/gui/ico/shinestacker.png,sha256=HTVd02AO0fuTrh9J-qaVlIBXaHwWK7GYdOAFe17IeB8,328817
55
- shinestacker/gui/img/close-round-line-icon.png,sha256=9HZwCjgni1s_JGUPUb_MoOfoe4tRZgM5OWzk92XFZlE,8019
56
- shinestacker/gui/img/forward-button-icon.png,sha256=lNw86T4TOEd_uokHYF8myGSGUXzdsHvmDAjlbE18Pgo,4788
57
- shinestacker/gui/img/play-button-round-icon.png,sha256=9j6Ks9mOGa-2cXyRFpimepAAvSaHzqJKBfxShRb4_dE,4595
58
- shinestacker/gui/img/plus-round-line-icon.png,sha256=LS068Hlu-CeBvJuB3dwwdJg1lZq6D5MUIv53lu1yKJA,7534
59
- shinestacker/retouch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
- shinestacker/retouch/base_filter.py,sha256=74GmzLjpPtn0Um0YOS8qLC1ZvhbvQX4L_AEDk-5H5nE,4717
61
- shinestacker/retouch/brush.py,sha256=dzD2FzSpBIPdJRmTZobcrQ1FrVd3tF__ZPnUplNE72s,357
62
- shinestacker/retouch/brush_gradient.py,sha256=F5SFhyzl8YTMqjJU3jK8BrIlLCYLUvITd5wz3cQE4xk,1453
63
- shinestacker/retouch/brush_preview.py,sha256=KlUOqA1uvLZRsz2peJ9NgsukyzsppJUw3XXr0NFCuhQ,5181
64
- shinestacker/retouch/brush_tool.py,sha256=m3qxyGipJth-lhB8syGSKmBPtXTQaIyaeJnpuCY3mSA,8694
65
- shinestacker/retouch/denoise_filter.py,sha256=eO0Cxo9xwsuiE6-JiWCFB5jf6U1kf2N3ftsDAEQ5sek,1982
66
- shinestacker/retouch/display_manager.py,sha256=XPbOBmoYc_jNA791WkWkOSaFHb0ztCZechl2p2KSlwQ,9597
67
- shinestacker/retouch/exif_data.py,sha256=uA9ck9skp8ztSUdX1SFrApgtqmxrHtfWW3vsry82H94,2026
68
- shinestacker/retouch/file_loader.py,sha256=723A_2w3cjn4rhvAzCq-__SWFelDRsMhkazgnb2h7Ig,4810
69
- shinestacker/retouch/filter_manager.py,sha256=SkioWTr6iFFpugUgZLg0a3m5b9EHdZAeyNFy39qk0z8,453
70
- shinestacker/retouch/icon_container.py,sha256=6gw1HO1bC2FrdB4dc_iH81DQuLjzuvRGksZ2hKLT9yA,585
71
- shinestacker/retouch/image_editor.py,sha256=ob2h-g9yIlFBMyEkVAkRRqiDpwykaUAMjpzAxKAtCRE,8336
72
- shinestacker/retouch/image_editor_ui.py,sha256=fjHAs7x_4jbL5WVBVEzyW3TQMcrITU3ZmglxAwen51o,17520
73
- shinestacker/retouch/image_filters.py,sha256=JF2a7VATO3CGQr5_OOIPi2k7b9HvHzrhhWS73x32t-A,2883
74
- shinestacker/retouch/image_viewer.py,sha256=4kovjI8s5MWWA98oqNiQfe4xZvNRL_-UwnmSVK9r-gE,18639
75
- shinestacker/retouch/io_gui_handler.py,sha256=iEnyZ0Q1VJCXM5xf0rBFhBn4hFmGxOlIYjH8u1zDnT4,11348
76
- shinestacker/retouch/io_manager.py,sha256=JUAA--AK0mVa1PTErJTnBFjaXIle5Qs7Ow0Wkd8at0o,2437
77
- shinestacker/retouch/layer_collection.py,sha256=cvAW6nbG-KdhbN6XI4SrhGwvqTYGPyrZBLWz-uZkIJ0,5672
78
- shinestacker/retouch/shortcuts_help.py,sha256=dlt7OSAr9thYuoEPlirTU_YRzv5xP9vy2-9mZO7GVAA,3308
79
- shinestacker/retouch/undo_manager.py,sha256=_ekbcOLcPbQLY7t-o8wf-b1uA6OPY9rRyLM-KqMlQRo,3257
80
- shinestacker/retouch/unsharp_mask_filter.py,sha256=hNJlqXYjf9Nd8KlVy09fd4TxrHa9Ofef0ZLSMHjLL6I,3481
81
- shinestacker/retouch/white_balance_filter.py,sha256=2krwdz0X6qLWuCIEQcPtSQA_txfAsl7QUzfdsOLBrBU,4878
82
- shinestacker-0.5.0.dist-info/licenses/LICENSE,sha256=pWgb-bBdsU2Gd2kwAXxketnm5W_2u8_fIeWEgojfrxs,7651
83
- shinestacker-0.5.0.dist-info/METADATA,sha256=m4TX-tMSojm4PPLWN_MuOixF0daNqkVC1_igTn-tjDA,5202
84
- shinestacker-0.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
85
- shinestacker-0.5.0.dist-info/entry_points.txt,sha256=SY6g1LqtMmp23q1DGwLUDT_dhLX9iss8DvWkiWLyo_4,166
86
- shinestacker-0.5.0.dist-info/top_level.txt,sha256=MhijwnBVX5psfsyX8JZjqp3SYiWPsKe69f3Gnyze4Fw,13
87
- shinestacker-0.5.0.dist-info/RECORD,,