shinestacker 0.3.2__py3-none-any.whl → 0.3.4__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 (71) hide show
  1. shinestacker/__init__.py +2 -1
  2. shinestacker/_version.py +1 -1
  3. shinestacker/algorithms/__init__.py +3 -2
  4. shinestacker/algorithms/align.py +102 -64
  5. shinestacker/algorithms/balance.py +89 -42
  6. shinestacker/algorithms/base_stack_algo.py +42 -0
  7. shinestacker/algorithms/core_utils.py +6 -6
  8. shinestacker/algorithms/denoise.py +4 -1
  9. shinestacker/algorithms/depth_map.py +28 -39
  10. shinestacker/algorithms/exif.py +43 -38
  11. shinestacker/algorithms/multilayer.py +48 -28
  12. shinestacker/algorithms/noise_detection.py +34 -23
  13. shinestacker/algorithms/pyramid.py +42 -42
  14. shinestacker/algorithms/sharpen.py +1 -0
  15. shinestacker/algorithms/stack.py +42 -41
  16. shinestacker/algorithms/stack_framework.py +111 -65
  17. shinestacker/algorithms/utils.py +12 -11
  18. shinestacker/algorithms/vignetting.py +48 -22
  19. shinestacker/algorithms/white_balance.py +1 -0
  20. shinestacker/app/about_dialog.py +6 -2
  21. shinestacker/app/app_config.py +1 -0
  22. shinestacker/app/gui_utils.py +20 -0
  23. shinestacker/app/help_menu.py +1 -0
  24. shinestacker/app/main.py +9 -18
  25. shinestacker/app/open_frames.py +5 -4
  26. shinestacker/app/project.py +5 -16
  27. shinestacker/app/retouch.py +5 -17
  28. shinestacker/core/colors.py +4 -4
  29. shinestacker/core/core_utils.py +1 -1
  30. shinestacker/core/exceptions.py +2 -1
  31. shinestacker/core/framework.py +46 -33
  32. shinestacker/core/logging.py +9 -10
  33. shinestacker/gui/action_config.py +253 -197
  34. shinestacker/gui/actions_window.py +32 -28
  35. shinestacker/gui/colors.py +1 -0
  36. shinestacker/gui/gui_images.py +7 -3
  37. shinestacker/gui/gui_logging.py +3 -2
  38. shinestacker/gui/gui_run.py +53 -38
  39. shinestacker/gui/main_window.py +69 -25
  40. shinestacker/gui/new_project.py +35 -2
  41. shinestacker/gui/project_converter.py +21 -20
  42. shinestacker/gui/project_editor.py +45 -52
  43. shinestacker/gui/project_model.py +15 -23
  44. shinestacker/retouch/{filter_base.py → base_filter.py} +7 -4
  45. shinestacker/retouch/brush.py +1 -0
  46. shinestacker/retouch/brush_gradient.py +17 -3
  47. shinestacker/retouch/brush_preview.py +14 -10
  48. shinestacker/retouch/brush_tool.py +28 -19
  49. shinestacker/retouch/denoise_filter.py +3 -2
  50. shinestacker/retouch/display_manager.py +11 -5
  51. shinestacker/retouch/exif_data.py +1 -0
  52. shinestacker/retouch/file_loader.py +13 -9
  53. shinestacker/retouch/filter_manager.py +1 -0
  54. shinestacker/retouch/image_editor.py +14 -48
  55. shinestacker/retouch/image_editor_ui.py +10 -5
  56. shinestacker/retouch/image_filters.py +4 -2
  57. shinestacker/retouch/image_viewer.py +33 -31
  58. shinestacker/retouch/io_gui_handler.py +25 -13
  59. shinestacker/retouch/io_manager.py +3 -2
  60. shinestacker/retouch/layer_collection.py +79 -23
  61. shinestacker/retouch/shortcuts_help.py +1 -0
  62. shinestacker/retouch/undo_manager.py +7 -0
  63. shinestacker/retouch/unsharp_mask_filter.py +3 -2
  64. shinestacker/retouch/white_balance_filter.py +11 -6
  65. {shinestacker-0.3.2.dist-info → shinestacker-0.3.4.dist-info}/METADATA +10 -4
  66. shinestacker-0.3.4.dist-info/RECORD +86 -0
  67. shinestacker-0.3.2.dist-info/RECORD +0 -85
  68. {shinestacker-0.3.2.dist-info → shinestacker-0.3.4.dist-info}/WHEEL +0 -0
  69. {shinestacker-0.3.2.dist-info → shinestacker-0.3.4.dist-info}/entry_points.txt +0 -0
  70. {shinestacker-0.3.2.dist-info → shinestacker-0.3.4.dist-info}/licenses/LICENSE +0 -0
  71. {shinestacker-0.3.2.dist-info → shinestacker-0.3.4.dist-info}/top_level.txt +0 -0
@@ -3,11 +3,12 @@ import cv2
3
3
  from .. algorithms.utils import read_img, validate_image, get_img_metadata
4
4
  from .. algorithms.exif import get_exif, write_image_with_exif_data
5
5
  from .. algorithms.multilayer import write_multilayer_tiff_from_images
6
+ from .layer_collection import LayerCollectionHandler
6
7
 
7
8
 
8
- class IOManager:
9
+ class IOManager(LayerCollectionHandler):
9
10
  def __init__(self, layer_collection):
10
- layer_collection.add_to(self)
11
+ super().__init__(layer_collection)
11
12
  self.current_file_path = ''
12
13
  self.exif_path = ''
13
14
  self.exif_data = None
@@ -1,31 +1,15 @@
1
+ # pylint: disable=C0114, C0115, C0116, R0904
1
2
  import numpy as np
2
3
 
3
4
 
4
5
  class LayerCollection:
5
- def add_to(self, obj):
6
- obj.layer_collection = self
7
- obj.master_layer = lambda: obj.layer_collection.master_layer
8
- obj.current_layer = lambda: obj.layer_collection.current_layer()
9
- obj.layer_stack = lambda: obj.layer_collection.layer_stack
10
- obj.layer_labels = lambda: obj.layer_collection.layer_labels
11
- obj.set_layer_label = lambda i, val: obj.layer_collection.set_layer_label(i, val)
12
- obj.set_layer_labels = lambda labels: obj.layer_collection.set_layer_labels(labels)
13
- obj.current_layer_idx = lambda: obj.layer_collection.current_layer_idx
14
- obj.has_no_master_layer = lambda: obj.layer_collection.has_no_master_layer()
15
- obj.has_master_layer = lambda: obj.layer_collection.has_master_layer()
16
- obj.set_layer_stack = lambda stk: obj.layer_collection.set_layer_stack(stk)
17
- obj.set_master_layer = lambda img: obj.layer_collection.set_master_layer(img)
18
- obj.add_layer_label = lambda label: obj.layer_collection.add_layer_label(label)
19
- obj.add_layer = lambda img: obj.layer_collection.add_layer(img)
20
- obj.master_layer_copy = lambda: obj.layer_collection.master_layer_copy
21
- obj.copy_master_layer = lambda: obj.layer_collection.copy_master_layer()
22
- obj.set_current_layer_idx = lambda idx: obj.layer_collection.set_current_layer_idx(idx)
23
- obj.sort_layers = lambda order: obj.layer_collection.sort_layers(order)
24
- obj.number_of_layers = lambda: obj.layer_collection.number_of_layers()
25
- obj.valid_current_layer_idx = lambda: obj.layer_collection.valid_current_layer_idx()
26
-
27
6
  def __init__(self):
28
- self.reset()
7
+ self.master_layer = None
8
+ self.master_layer_copy = None
9
+ self.layer_stack = None
10
+ self.layer_labels = []
11
+ self.current_layer_idx = 0
12
+ self.sorted_indices = None
29
13
 
30
14
  def reset(self):
31
15
  self.master_layer = None
@@ -33,6 +17,7 @@ class LayerCollection:
33
17
  self.layer_stack = None
34
18
  self.layer_labels = []
35
19
  self.current_layer_idx = 0
20
+ self.sorted_indices = None
36
21
 
37
22
  def has_master_layer(self):
38
23
  return self.master_layer is not None
@@ -75,6 +60,9 @@ class LayerCollection:
75
60
  def set_master_layer(self, img):
76
61
  self.master_layer = img
77
62
 
63
+ def restore_master_layer(self):
64
+ self.master_layer = self.master_layer_copy.copy()
65
+
78
66
  def copy_master_layer(self):
79
67
  self.master_layer_copy = self.master_layer.copy()
80
68
 
@@ -116,3 +104,71 @@ class LayerCollection:
116
104
  self.master_layer.setflags(write=True)
117
105
  if self.current_layer_idx >= self.number_of_layers():
118
106
  self.current_layer_idx = self.number_of_layers() - 1
107
+
108
+
109
+ class LayerCollectionHandler:
110
+ def __init__(self, layer_collection=None):
111
+ self.layer_collection = layer_collection
112
+
113
+ def set_layer_collection(self, coll):
114
+ self.layer_collection = coll
115
+
116
+ def master_layer(self):
117
+ return self.layer_collection.master_layer
118
+
119
+ def current_layer(self):
120
+ return self.layer_collection.current_layer()
121
+
122
+ def layer_stack(self):
123
+ return self.layer_collection.layer_stack
124
+
125
+ def layer_labels(self):
126
+ return self.layer_collection.layer_labels
127
+
128
+ def set_layer_label(self, i, val):
129
+ self.layer_collection.set_layer_label(i, val)
130
+
131
+ def set_layer_labels(self, labels):
132
+ self.layer_collection.set_layer_labels(labels)
133
+
134
+ def current_layer_idx(self):
135
+ return self.layer_collection.current_layer_idx
136
+
137
+ def has_no_master_layer(self):
138
+ return self.layer_collection.has_no_master_layer()
139
+
140
+ def has_master_layer(self):
141
+ return self.layer_collection.has_master_layer()
142
+
143
+ def set_layer_stack(self, stk):
144
+ self.layer_collection.set_layer_stack(stk)
145
+
146
+ def set_master_layer(self, img):
147
+ self.layer_collection.set_master_layer(img)
148
+
149
+ def add_layer_label(self, label):
150
+ self.layer_collection.add_layer_label(label)
151
+
152
+ def add_layer(self, img):
153
+ self.layer_collection.add_layer(img)
154
+
155
+ def master_layer_copy(self):
156
+ return self.layer_collection.master_layer_copy
157
+
158
+ def copy_master_layer(self):
159
+ self.layer_collection.copy_master_layer()
160
+
161
+ def restore_master_layer(self):
162
+ self.layer_collection.restore_master_layer()
163
+
164
+ def set_current_layer_idx(self, idx):
165
+ self.layer_collection.set_current_layer_idx(idx)
166
+
167
+ def sort_layers(self, order):
168
+ self.layer_collection.sort_layers(order)
169
+
170
+ def number_of_layers(self):
171
+ return self.layer_collection.number_of_layers()
172
+
173
+ def valid_current_layer_idx(self):
174
+ return self.layer_collection.valid_current_layer_idx()
@@ -1,3 +1,4 @@
1
+ # pylint: disable=C0114, C0115, C0116, E0611
1
2
  import os
2
3
  from PySide6.QtWidgets import (QFormLayout, QHBoxLayout, QPushButton, QDialog,
3
4
  QLabel, QVBoxLayout, QWidget)
@@ -1,3 +1,4 @@
1
+ # pylint: disable=C0114, C0115, C0116, E0611
1
2
  from PySide6.QtCore import QObject, Signal
2
3
  from .. config.gui_constants import gui_constants
3
4
 
@@ -7,6 +8,12 @@ class UndoManager(QObject):
7
8
 
8
9
  def __init__(self):
9
10
  super().__init__()
11
+ self.x_start = None
12
+ self.y_start = None
13
+ self.x_end = None
14
+ self.y_end = None
15
+ self.undo_stack = None
16
+ self.redo_stack = None
10
17
  self.reset()
11
18
 
12
19
  def reset(self):
@@ -1,6 +1,8 @@
1
+ # pylint: disable=C0114, C0115, C0116, E0611, W0221, R0902, R0914
1
2
  from PySide6.QtWidgets import QHBoxLayout, QLabel, QSlider, QCheckBox, QDialogButtonBox
2
3
  from PySide6.QtCore import Qt, QTimer
3
- from .filter_base import BaseFilter
4
+ from .. algorithms.sharpen import unsharp_mask
5
+ from .base_filter import BaseFilter
4
6
 
5
7
 
6
8
  class UnsharpMaskFilter(BaseFilter):
@@ -80,5 +82,4 @@ class UnsharpMaskFilter(BaseFilter):
80
82
  )
81
83
 
82
84
  def apply(self, image, radius, amount, threshold):
83
- from .. algorithms.sharpen import unsharp_mask
84
85
  return unsharp_mask(image, radius, amount, threshold)
@@ -1,9 +1,10 @@
1
- from PySide6.QtWidgets import (QHBoxLayout,
2
- QPushButton, QFrame, QVBoxLayout, QLabel, QDialog, QApplication, QSlider,
3
- QCheckBox, QDialogButtonBox)
1
+ # pylint: disable=C0114, C0115, C0116, E0611, W0221, R0913, R0914, R0917
2
+ from PySide6.QtWidgets import (QHBoxLayout, QPushButton, QFrame, QVBoxLayout, QLabel, QDialog,
3
+ QApplication, QSlider, QCheckBox, QDialogButtonBox)
4
4
  from PySide6.QtCore import Qt, QTimer
5
5
  from PySide6.QtGui import QCursor
6
- from .filter_base import BaseFilter
6
+ from .. algorithms.white_balance import white_balance_from_rgb
7
+ from .base_filter import BaseFilter
7
8
 
8
9
 
9
10
  class WhiteBalanceFilter(BaseFilter):
@@ -15,6 +16,7 @@ class WhiteBalanceFilter(BaseFilter):
15
16
  self.value_labels = {}
16
17
  self.color_preview = None
17
18
  self.preview_timer = None
19
+ self.original_mouse_press = None
18
20
 
19
21
  def setup_ui(self, dlg, layout, do_preview, restore_original, init_val=None):
20
22
  if init_val:
@@ -48,7 +50,11 @@ class WhiteBalanceFilter(BaseFilter):
48
50
  preview_check = QCheckBox("Preview")
49
51
  preview_check.setChecked(True)
50
52
  layout.addWidget(preview_check)
51
- button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Reset | QDialogButtonBox.Cancel)
53
+ button_box = QDialogButtonBox(
54
+ QDialogButtonBox.Ok |
55
+ QDialogButtonBox.Reset |
56
+ QDialogButtonBox.Cancel
57
+ )
52
58
  layout.addWidget(button_box)
53
59
  self.preview_timer = QTimer()
54
60
  self.preview_timer.setSingleShot(True)
@@ -107,5 +113,4 @@ class WhiteBalanceFilter(BaseFilter):
107
113
  return tuple(self.sliders[n].value() for n in ("R", "G", "B"))
108
114
 
109
115
  def apply(self, image, r, g, b):
110
- from .. algorithms.white_balance import white_balance_from_rgb
111
116
  return white_balance_from_rgb(image, (r, g, b))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shinestacker
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: ShineStacker
5
5
  Author-email: Luca Lista <luka.lista@gmail.com>
6
6
  License-Expression: LGPL-3.0
@@ -36,11 +36,17 @@ Dynamic: license-file
36
36
  [![CI multiplatform](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml/badge.svg)](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml)
37
37
  [![PyPI version](https://img.shields.io/pypi/v/shinestacker?color=success)](https://pypi.org/project/shinestacker/)
38
38
  [![Python Versions](https://img.shields.io/pypi/pyversions/shinestacker)](https://pypi.org/project/shinestacker/)
39
+ [![Qt Versions](https://img.shields.io/badge/Qt-6-blue.svg?&logo=Qt&logoWidth=18&logoColor=white)](https://www.qt.io/qt-for-python)
39
40
  [![codecov](https://codecov.io/github/lucalista/shinestacker/graph/badge.svg?token=Y5NKW6VH5G)](https://codecov.io/github/lucalista/shinestacker)
41
+ [![pylint](https://img.shields.io/badge/PyLint-9.98-yellow?logo=python&logoColor=white)](https://github.com/lucalista/shinestacker/blob/main/.github/workflows/pylint.yml)
40
42
  [![Documentation Status](https://readthedocs.org/projects/shinestacker/badge/?version=latest)](https://shinestacker.readthedocs.io/en/latest/?badge=latest)
41
43
 
44
+
45
+
42
46
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400" referrerpolicy="no-referrer"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400" referrerpolicy="no-referrer">
43
47
 
48
+ <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/coffee.gif' width="400" referrerpolicy="no-referrer"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/coffee_stack.jpg' width="400" referrerpolicy="no-referrer">
49
+
44
50
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/coins.gif' width="400" referrerpolicy="no-referrer"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/coins_stack.jpg' width="400" referrerpolicy="no-referrer">
45
51
  > **Focus stacking** for microscopy, macro photography, and computational imaging
46
52
 
@@ -48,7 +54,7 @@ Dynamic: license-file
48
54
  - 🚀 **Batch Processing**: Align, balance, and stack hundreds of images
49
55
  - 🎨 **Hybrid Workflows**: Combine Python scripting with GUI refinement
50
56
  - 🧩 **Modular Architecture**: Mix-and-match processing modules
51
- - 🖌️ **Non-Destructive Editing**: Save multilayer TIFFs for retouching
57
+ - 🖌️ **Retouch Editing**: Final interactive retouch of stacked image from individual frames
52
58
  - 📊 **Jupyter Integration**: Reproducible research notebooks
53
59
 
54
60
  ## Interactive GUI
@@ -63,9 +69,9 @@ The GUI has two main working areas:
63
69
 
64
70
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/gui-retouch.png' width="600" referrerpolicy="no-referrer">
65
71
 
66
- # Documentation
72
+ # Resources
67
73
 
68
- 📖 [Main documentation](https://github.com/lucalista/shinestacker/blob/main/docs/main.md) • 📝 [Changelog](https://github.com/lucalista/shinestacker/blob/main/CHANGELOG.md)
74
+ 🌍 [Website on WordPress](https://shinestacker.wordpress.com) • 📖 [Main documentation](https://shinestacker.readthedocs.io) • 📝 [Changelog](https://github.com/lucalista/shinestacker/blob/main/CHANGELOG.md)
69
75
 
70
76
 
71
77
  # Credits
@@ -0,0 +1,86 @@
1
+ shinestacker/__init__.py,sha256=uq2fjAw2z_6TpH3mOcWFZ98GoEPRsNhTAK8N0MMm_e8,448
2
+ shinestacker/_version.py,sha256=SH0xuWVUkyLHZJwWBZ8GJoeliTeYFcqA6TWJgrkLv-U,21
3
+ shinestacker/algorithms/__init__.py,sha256=c4kRrdTLlVI70Q16XkI1RSmz5MD7npDqIpO_02jTG6g,747
4
+ shinestacker/algorithms/align.py,sha256=1CAnVhxaYO-SUd86Mmj7lTmaqlrmUWlF-HEM5341gcs,17166
5
+ shinestacker/algorithms/balance.py,sha256=ZBcw2Ck-CfuobIG1FxFsGVjnLvD1rtVNrTO-GrFbi3Q,16441
6
+ shinestacker/algorithms/base_stack_algo.py,sha256=GeUASZ92bjo_YYpWYmFfoPDJBo-SgCpSTYLFH3gjnSw,1415
7
+ shinestacker/algorithms/core_utils.py,sha256=XJyHDUFXmN4JhbOjJqhP4dJW75B69oZaaWQrSXHUk5o,575
8
+ shinestacker/algorithms/denoise.py,sha256=GL3Z4_6MHxSa7Wo4ZzQECZS87tHBFqO0sIVF_jPuYQU,426
9
+ shinestacker/algorithms/depth_map.py,sha256=b88GqbRXEU3wCXBxMcStlgZ4sFJicoiZfJMD30Z4b98,7364
10
+ shinestacker/algorithms/exif.py,sha256=gY9s6Cd4g4swo5qEjSbzuVIvl1GImCYu6ytOO9WrV0I,9435
11
+ shinestacker/algorithms/multilayer.py,sha256=4Y6XlNJHFW74iNDFIeq_zdVtwLBnrieeMd708zJX-lo,8994
12
+ shinestacker/algorithms/noise_detection.py,sha256=5PZ3sucWiSK5f4PKY2SW1CIzTtgs_o7g48b6JlM3tTc,8597
13
+ shinestacker/algorithms/pyramid.py,sha256=zQdN2cr26M2iIywjr_xtknY9XvA2cc6wjMmiNOJf3Wc,8288
14
+ shinestacker/algorithms/sharpen.py,sha256=h7PMJBYxucg194Usp_6pvItPUMFYbT-ebAc_-7XBFUw,949
15
+ shinestacker/algorithms/stack.py,sha256=KTtoPGZYocSYqK4zqvhbMyk6M69L2HhNSDG9ayomASo,4852
16
+ shinestacker/algorithms/stack_framework.py,sha256=8hRvAjoFyx4vT34pq1XZAh-62kw__ycI3fLiHgODMe0,12216
17
+ shinestacker/algorithms/utils.py,sha256=VLm6eZmcAk2QPvomT4d1q56laJSYfbCQmiwI2Rmuu_s,2171
18
+ shinestacker/algorithms/vignetting.py,sha256=Z6OB5ahgQCvE4J8Gy7EhtHHoPXoM2_3jnisWM1x_r6c,7436
19
+ shinestacker/algorithms/white_balance.py,sha256=PMKsBtxOSn5aRr_Gkx1StHS4eN6kBN2EhNnhg4UG24g,501
20
+ shinestacker/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ shinestacker/app/about_dialog.py,sha256=QzZgTcLvkSP3_FhmPOUnwQ_YSxwJdeFrU2IAVYKDgeg,1050
22
+ shinestacker/app/app_config.py,sha256=Rde_EKfM0tAs6a1qtiNkr6Bkodg5hZc6XW4hmQoQoac,1169
23
+ shinestacker/app/gui_utils.py,sha256=ptbUKjv5atbx5vW912_j8BVmDZpovAqZDEC48d0R2vA,2331
24
+ shinestacker/app/help_menu.py,sha256=T6_L3CGOkJs5fvFf3XLkIehk2khrdTE-nXo5Aj8VR94,514
25
+ shinestacker/app/main.py,sha256=RAf9WiCipYLK1rrwnXyL1sWq_28zDl9Z_eipfrdtSuY,6421
26
+ shinestacker/app/open_frames.py,sha256=bsu32iJSYJQLe_tQQbvAU5DuMDVX6MRuNdE7B5lojZc,1488
27
+ shinestacker/app/project.py,sha256=ir98-zogYmvx2QYvFbAaBUqLL03qWYkoMOIvLvmQy_w,2736
28
+ shinestacker/app/retouch.py,sha256=ZQ-nRKnHo6xurcP34RNqaAWkmuGBjJ5jE05hTQ_ycis,2482
29
+ shinestacker/config/__init__.py,sha256=aXxi-LmAvXd0daIFrVnTHE5OCaYeK1uf1BKMr7oaXQs,197
30
+ shinestacker/config/config.py,sha256=BmcY79Ng3bN7HvYK7DzkGlrk2kTfV5R4gKTln87tfWs,1539
31
+ shinestacker/config/constants.py,sha256=79bOcE44MZ0WuAVPjDwwhvNrsQTlHGyIOwmqwlLOfMU,5776
32
+ shinestacker/config/gui_constants.py,sha256=002r96jtxV4Acel7q5NgECrcsDJzW-kOStEHqam-5Gg,2492
33
+ shinestacker/core/__init__.py,sha256=IUEIx6SQ3DygDEHN3_E6uKpHjHtUa4a_U_1dLd_8yEU,484
34
+ shinestacker/core/colors.py,sha256=kr_tJA1iRsdck2JaYDb2lS-codZ4Ty9gdu3kHfiWvuM,1340
35
+ shinestacker/core/core_utils.py,sha256=ulJhzen5McAb5n6wWNA_KB4U_PdTEr-H2TCQkVKUaOw,1421
36
+ shinestacker/core/exceptions.py,sha256=2-noG-ORAGdvDhL8jBQFs0xxZS4fI6UIkMqrWekgk2c,1618
37
+ shinestacker/core/framework.py,sha256=3Q3zalyZeCiUHXYbBiYadWNdtyD_3j3dcymk5_3NajM,7063
38
+ shinestacker/core/logging.py,sha256=9SuSSy9Usbh7zqmLYMqkmy-VBkOJW000lwqAR0XQs30,3067
39
+ shinestacker/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ shinestacker/gui/action_config.py,sha256=z5rztJDmOIyXUm3CiRoXFLn1AWHqHDYkcUkLGK5mzbE,49539
41
+ shinestacker/gui/actions_window.py,sha256=W9XNjiTbsBJ-ZFdb5wo1eGD8OlSBpsuqyuJsKdWq_hI,13522
42
+ shinestacker/gui/colors.py,sha256=zgLRcC3fAzklx7zzyjLEsMX2i64YTxGUmQM2woYBZuw,1344
43
+ shinestacker/gui/gui_images.py,sha256=e0KAXSPruZoRHrajfdlmOKBYoRJJQBDan1jgs7YFltY,5678
44
+ shinestacker/gui/gui_logging.py,sha256=ESlk1EAQMdoT8pCZDFsvtU1UtF4h2GKv3wAhxJYxNis,8213
45
+ shinestacker/gui/gui_run.py,sha256=bYXX4N__Ez7JMIJtVcTmLF2PJ3y9bCd-uvlOHsV-4gg,16230
46
+ shinestacker/gui/main_window.py,sha256=z14PWRVDRbuySM05YCCFrn1DPU3U96xwQHy730oiLkw,28577
47
+ shinestacker/gui/new_project.py,sha256=nr05vfmMH-LsKiLL_qOanSr35-6AZwv7q_CXAXXEFFc,8443
48
+ shinestacker/gui/project_converter.py,sha256=v-oldaw77VLsywhQcl5uhTtPD7GbGFeJo33JJRl3aG4,7453
49
+ shinestacker/gui/project_editor.py,sha256=5A2CmIfLKoRSGfxgyYEzVNDdrwXyc65de-pzlYPAUKo,21296
50
+ shinestacker/gui/project_model.py,sha256=89L0IDSAqRK2mvU1EVIrcsJas8CU-aTzUIjdL1Cv0mw,4421
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=sU2reqQpC3b-Q1iiTk2fWTtruakQvhZWC2MTRt74fFM,4228
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=kwX58_gC_Fep6zowDqOs3nG2wCIc8wrJdokDADGm6K0,8016
65
+ shinestacker/retouch/denoise_filter.py,sha256=Z6oG5YVG172t1titu1KOgnKFSW8My2vzlTOSf5Ey5jY,2212
66
+ shinestacker/retouch/display_manager.py,sha256=54NRdlyVj_7GzJ7hmKf8Hnf3lJJx2jVSSpWedj-5pIc,7298
67
+ shinestacker/retouch/exif_data.py,sha256=UB_CwoVN5mMLU6PfJCRaZOfarFR77a11mVaxbYZ4v-Y,2301
68
+ shinestacker/retouch/file_loader.py,sha256=723A_2w3cjn4rhvAzCq-__SWFelDRsMhkazgnb2h7Ig,4810
69
+ shinestacker/retouch/filter_manager.py,sha256=SkioWTr6iFFpugUgZLg0a3m5b9EHdZAeyNFy39qk0z8,453
70
+ shinestacker/retouch/image_editor.py,sha256=co5zUufgeb1WrD3aF1RVPh1MbcC9-92HSUa2iROnKk4,8503
71
+ shinestacker/retouch/image_editor_ui.py,sha256=vfBALDuHtqSWIPmyfUirkygM1guwQG-gHo0AH0x8_jU,15712
72
+ shinestacker/retouch/image_filters.py,sha256=JF2a7VATO3CGQr5_OOIPi2k7b9HvHzrhhWS73x32t-A,2883
73
+ shinestacker/retouch/image_viewer.py,sha256=oqBgaanPXWjzIaox5KSRhYOHoGvoYnWm7sqW3cLoY24,14803
74
+ shinestacker/retouch/io_gui_handler.py,sha256=2jkbPXew95rMKO2aC9hwZJGtZRg3wCCtXI0SFFiNHUI,9089
75
+ shinestacker/retouch/io_manager.py,sha256=sNcZVEttiVdxNBVs39ZvexqOcvtjl2CvJs6BVqmGvOM,2148
76
+ shinestacker/retouch/layer_collection.py,sha256=j1NiGGtLZ3OwrftBVNT4rb0Kq0CfWAB3t2bUrqHx1Sk,5608
77
+ shinestacker/retouch/shortcuts_help.py,sha256=wjCw2TiUBaPx1OqpdZlRPsLbyLhIZkoffz9wcODtQnA,3794
78
+ shinestacker/retouch/undo_manager.py,sha256=_ekbcOLcPbQLY7t-o8wf-b1uA6OPY9rRyLM-KqMlQRo,3257
79
+ shinestacker/retouch/unsharp_mask_filter.py,sha256=u6QDAebzAUqRvJtXyMLdXy-G0zEGb-43LzaKkK4kQ2A,3704
80
+ shinestacker/retouch/white_balance_filter.py,sha256=odS_QTTLBzuN0gzhGqCC3T5mNRwE-epxPXraKhj5VQM,5132
81
+ shinestacker-0.3.4.dist-info/licenses/LICENSE,sha256=cBN0P3F6BWFkfOabkhuTxwJnK1B0v50jmmzZJjGGous,80
82
+ shinestacker-0.3.4.dist-info/METADATA,sha256=vR3xbqQFRJErmGEx0k0Mhnsamt_iHlYeuwghqdbcmus,5136
83
+ shinestacker-0.3.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
84
+ shinestacker-0.3.4.dist-info/entry_points.txt,sha256=SY6g1LqtMmp23q1DGwLUDT_dhLX9iss8DvWkiWLyo_4,166
85
+ shinestacker-0.3.4.dist-info/top_level.txt,sha256=MhijwnBVX5psfsyX8JZjqp3SYiWPsKe69f3Gnyze4Fw,13
86
+ shinestacker-0.3.4.dist-info/RECORD,,
@@ -1,85 +0,0 @@
1
- shinestacker/__init__.py,sha256=35QgHh92rTqveh8kp-4T-iWPOVFKmBAtfmSE7Ytl4k0,416
2
- shinestacker/_version.py,sha256=64UBVh2KX7E-WVG4ZyY1dUiW9jGXZloWZk1N9nEUC2k,21
3
- shinestacker/algorithms/__init__.py,sha256=X9nwToaB13GAACoaE-K0o9R1Jt7g9xSzeJI8Ra2GcL8,722
4
- shinestacker/algorithms/align.py,sha256=As7MIfjoJc_1vJ058iwP7b_PnDnfYsBQ1JNZ4GX5ZU4,16529
5
- shinestacker/algorithms/balance.py,sha256=wFVfKzZTwHlvqqJ6Fd8CsUQKkz7I9Dw7uP98esJ-_K0,15640
6
- shinestacker/algorithms/core_utils.py,sha256=3mvJVDDfzMOboP724iM_5WT-pLFFoGAhwcXsQN8dBYo,552
7
- shinestacker/algorithms/denoise.py,sha256=C59la4DEh6uPZIDgmaZIqgxdxDYBxXRxgQBLLBvSlBA,374
8
- shinestacker/algorithms/depth_map.py,sha256=hx6yyCjLKiu3Wi5uZFXiixEfOBxfieNQ9xH9cp5zD0Y,7844
9
- shinestacker/algorithms/exif.py,sha256=VS3qbLRVlbZ8_z8hYgGVV4BSmwWzR0reN_G0XV3hzAI,9364
10
- shinestacker/algorithms/multilayer.py,sha256=Fm-WZqH4DAEOAyC0QpPaMH3VaG5cEPX9rqKsAyWpELs,8694
11
- shinestacker/algorithms/noise_detection.py,sha256=GMX5_Pd24tL-aSt28ad94wsCiCOBXYXc3Sf4IySbxfo,8362
12
- shinestacker/algorithms/pyramid.py,sha256=iUbgRI0p0uzEXcZetAm3hgzwiXhF4mIaNxYMUUpJFeE,8589
13
- shinestacker/algorithms/sharpen.py,sha256=KtTDIytJW7z4Oj-E1FcxKvhzz27xLX2CCSwJAG_QRUY,911
14
- shinestacker/algorithms/stack.py,sha256=EZm2SIuoh8c7hgySB2tQGydKYQjJa2hEqR8YNzIeRuQ,5194
15
- shinestacker/algorithms/stack_framework.py,sha256=aJBjkQFxiPNjnsnZyoF8lXKR17tm0rTO7puEu_ZvASU,10928
16
- shinestacker/algorithms/utils.py,sha256=Z81_tHTjzH_8oJ44UmgukHtm1Wbbm8g3YTCy4jBYrWo,2164
17
- shinestacker/algorithms/vignetting.py,sha256=EiD4O8GJPGOqByjDAfFj-de4cb64Qf685RujqlBgvX0,6774
18
- shinestacker/algorithms/white_balance.py,sha256=AN33zegS8hMJK7I-7UZVmjaOg5PXy9wTnDei12EnPWg,470
19
- shinestacker/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- shinestacker/app/about_dialog.py,sha256=G_2hRQFpo96q0H8z02fMZ0Jl_2-PpnwNxqISY7Xn5Kg,885
21
- shinestacker/app/app_config.py,sha256=tQ1JBTG2gtHO1UbJYJjjYUBCakmtZpafvMUTHb5OyUo,1117
22
- shinestacker/app/gui_utils.py,sha256=C5ehbYyoIcBweFTfdQcjsILAcWpMPrVLMbYz0ZM-EcM,1571
23
- shinestacker/app/help_menu.py,sha256=ofFhZMPTz7lQ-_rsu30yAxbLA-Zq_kkRGXxPMukaG08,476
24
- shinestacker/app/main.py,sha256=insz1oxeDlZQWNKo7DGaLmRrc8PZVD7brPRrWE1SWvk,6894
25
- shinestacker/app/open_frames.py,sha256=B66j1MhghMwQYqVJNuC0d7yWGuuWtM2ANOpW86PpRoI,1431
26
- shinestacker/app/project.py,sha256=xtuA8SRoWINpHcLTApBL3RYRd0ADrczrAaq_xtT3cZI,3234
27
- shinestacker/app/retouch.py,sha256=6Sa3ngUqj_Wn5gZBJNZeM-JxeGvXWmJZAa2Jj99t-xk,3012
28
- shinestacker/config/__init__.py,sha256=aXxi-LmAvXd0daIFrVnTHE5OCaYeK1uf1BKMr7oaXQs,197
29
- shinestacker/config/config.py,sha256=BmcY79Ng3bN7HvYK7DzkGlrk2kTfV5R4gKTln87tfWs,1539
30
- shinestacker/config/constants.py,sha256=79bOcE44MZ0WuAVPjDwwhvNrsQTlHGyIOwmqwlLOfMU,5776
31
- shinestacker/config/gui_constants.py,sha256=002r96jtxV4Acel7q5NgECrcsDJzW-kOStEHqam-5Gg,2492
32
- shinestacker/core/__init__.py,sha256=IUEIx6SQ3DygDEHN3_E6uKpHjHtUa4a_U_1dLd_8yEU,484
33
- shinestacker/core/colors.py,sha256=HqelUiEAwsS9lS0Z4zA1NE-pgg8CuSl17FjnQ_M5srY,1368
34
- shinestacker/core/core_utils.py,sha256=DI6kriZSXkLF87Df8B8jG0BCvUBM7u16r1n-5QC5EY0,1428
35
- shinestacker/core/exceptions.py,sha256=XZWlnwXh-SGKvxxk61oLKOgQudtoH5bIX7RM0WnxNgI,1593
36
- shinestacker/core/framework.py,sha256=Nh_fF-y1WcJQpycCEsgYjtQUq0idkFa04KWzZuo5lK0,6907
37
- shinestacker/core/logging.py,sha256=YkKqCduU9FVYCBi26izHKmjyxlGMbwwpYbfn9AY1KeI,3155
38
- shinestacker/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- shinestacker/gui/action_config.py,sha256=YuKNd61XyxlUrd3H96e-9t6a_gLZQ-B7ZslQOtdWPHI,48410
40
- shinestacker/gui/actions_window.py,sha256=cj_-Okc0wIbV6S_KqycaFsX3BEM32cCSxCrNHUZLpFI,13442
41
- shinestacker/gui/colors.py,sha256=Af4ccwKfiElzA2poyx2QSU2xvxOdA5fFz0Y2YIqTj9Y,1292
42
- shinestacker/gui/gui_images.py,sha256=3HySCrldbYhUyxO0B1ckC2TLVg5nq94bBXjqsQzCyCA,5546
43
- shinestacker/gui/gui_logging.py,sha256=sN82OsGhMcZdgFMY4z-VbUYiRIsReN-ICaxi31M1J6E,8147
44
- shinestacker/gui/gui_run.py,sha256=LpBi1V91NrJpVpgS098lSgLtiege0aqcWIGwSbB8cL4,15701
45
- shinestacker/gui/main_window.py,sha256=KtMe6Hm74xk-lP3qcUsWAw0dzT7CynpdbZA_H651XN0,27203
46
- shinestacker/gui/new_project.py,sha256=0bcFg8iB8yxSom0itiO1f9bIcKrCAEgT8aSgUUKyomQ,7075
47
- shinestacker/gui/project_converter.py,sha256=d66pbBzaBgANpudJLW0tGUSfSy0PXNhs1M6R2o_Fd5E,7390
48
- shinestacker/gui/project_editor.py,sha256=s0IU3l3xO_JGovazOHhKkT1rraUWNVzyAua1dsUqJyg,21657
49
- shinestacker/gui/project_model.py,sha256=buzpxppLuoNWao7M2_FOPVpCBex2WgEcvqyq9dxvrz8,4524
50
- shinestacker/gui/ico/focus_stack_bkg.png,sha256=Q86TgqvKEi_IzKI8m6aZB2a3T40UkDtexf2PdeBM9XE,163151
51
- shinestacker/gui/ico/shinestacker.icns,sha256=m_6WQBx8sE9jQKwIRa_B5oa7_VcNn6e2TyijeQXPjwM,337563
52
- shinestacker/gui/ico/shinestacker.ico,sha256=yO0NaBWA0uFov_GqHuHQbymoqLtQKt5DPWpGGmRKie0,186277
53
- shinestacker/gui/ico/shinestacker.png,sha256=HTVd02AO0fuTrh9J-qaVlIBXaHwWK7GYdOAFe17IeB8,328817
54
- shinestacker/gui/img/close-round-line-icon.png,sha256=9HZwCjgni1s_JGUPUb_MoOfoe4tRZgM5OWzk92XFZlE,8019
55
- shinestacker/gui/img/forward-button-icon.png,sha256=lNw86T4TOEd_uokHYF8myGSGUXzdsHvmDAjlbE18Pgo,4788
56
- shinestacker/gui/img/play-button-round-icon.png,sha256=9j6Ks9mOGa-2cXyRFpimepAAvSaHzqJKBfxShRb4_dE,4595
57
- shinestacker/gui/img/plus-round-line-icon.png,sha256=LS068Hlu-CeBvJuB3dwwdJg1lZq6D5MUIv53lu1yKJA,7534
58
- shinestacker/retouch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
- shinestacker/retouch/brush.py,sha256=49YNdZp1dbfowh6HmLfxuHKz7Py9wkFQsN9-pH38P7Q,319
60
- shinestacker/retouch/brush_gradient.py,sha256=b7vEnluGkdUVXn7AIECEhQUh1OYbBFIv2UbW8exBRWg,1014
61
- shinestacker/retouch/brush_preview.py,sha256=uqhO1VpCs6lYLy-HT0QR-Sy8-KivnJnR03YSHJD_p0Y,4946
62
- shinestacker/retouch/brush_tool.py,sha256=e1o2OMtnFD_H6Dj0hkxHO0nR97pF4axCfEiBj0L8CP4,7989
63
- shinestacker/retouch/denoise_filter.py,sha256=RCviO8rk0ygcA9jfbG7n3fDX6xwloQH7u92fExX_NeE,2168
64
- shinestacker/retouch/display_manager.py,sha256=resqj_fDMZE8i7Bi8k4eO9s771qbqXB5uXuI5SdItqI,7031
65
- shinestacker/retouch/exif_data.py,sha256=VLo-vQu89QlbHZisE9vcWCKk0YhHdOMOJDvWuER6phQ,2256
66
- shinestacker/retouch/file_loader.py,sha256=TbPjiD9Vv-i3LCsPVcumYJ2DxgnLmQA6xYCiLCqbEcg,4565
67
- shinestacker/retouch/filter_base.py,sha256=GYpUnGl-RAWx7dLGAiTMkqYOetVCEnFzr97Tl2SyESg,4106
68
- shinestacker/retouch/filter_manager.py,sha256=IrzLYh1LiIeBYO-lzHcPZVv4FRJqGntZTv8hO6KlsV4,415
69
- shinestacker/retouch/image_editor.py,sha256=0xO_HPQruRjF0gRdsWPIOZjNPj0ma6y6MvN_mqvkFIQ,10506
70
- shinestacker/retouch/image_editor_ui.py,sha256=6Capd2uOBi-Zd7f9v4pFkxBqNFtvrFdHKW2d4Rf4Tio,15548
71
- shinestacker/retouch/image_filters.py,sha256=Pi3TMUdav1IDwckdnnJYaY6fABqFfCFRvjVyoMg3rGM,2803
72
- shinestacker/retouch/image_viewer.py,sha256=tvL4n7Sx4qr2XIPsRpjC93zD8fYtT-gYStKeMy8xuTU,14654
73
- shinestacker/retouch/io_gui_handler.py,sha256=FFUp3TKJKur_jcO3jtWdOPkAMR8-uIQ3O649y8S0F_A,8721
74
- shinestacker/retouch/io_manager.py,sha256=Z-ScRSnD8YobqgRiHpjIISyHRjZr_OceMfXv7tU4Sq0,2066
75
- shinestacker/retouch/layer_collection.py,sha256=usG1fObcQil-lq8ot7w1BtgJ_rBM8p6pE319NXUzkOY,4881
76
- shinestacker/retouch/shortcuts_help.py,sha256=iYwD7YGV2epNDwOBVDc99zqB9bbxLR_IUtanMJ-abPQ,3749
77
- shinestacker/retouch/undo_manager.py,sha256=5jWPsaERSh7TuWV5EbvqL6EsRS88Ct6VmM7FHxYzufs,3042
78
- shinestacker/retouch/unsharp_mask_filter.py,sha256=3lvV4H5uGTMXPT2Q41SXqi7wUVOuau1dn7CBbT7wzNk,3646
79
- shinestacker/retouch/white_balance_filter.py,sha256=h3TxwQ2uN_3tzVU22kr-5A6IeDzrJ1JpBd0jpHuuDvU,5011
80
- shinestacker-0.3.2.dist-info/licenses/LICENSE,sha256=cBN0P3F6BWFkfOabkhuTxwJnK1B0v50jmmzZJjGGous,80
81
- shinestacker-0.3.2.dist-info/METADATA,sha256=tzNHac7NHKCwXhjd-pRKsY9q6e9t-_7qiv5O_eKs4lM,4505
82
- shinestacker-0.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
83
- shinestacker-0.3.2.dist-info/entry_points.txt,sha256=SY6g1LqtMmp23q1DGwLUDT_dhLX9iss8DvWkiWLyo_4,166
84
- shinestacker-0.3.2.dist-info/top_level.txt,sha256=MhijwnBVX5psfsyX8JZjqp3SYiWPsKe69f3Gnyze4Fw,13
85
- shinestacker-0.3.2.dist-info/RECORD,,