shinestacker 1.7.0__py3-none-any.whl → 1.8.1__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.
- shinestacker/_version.py +1 -1
- shinestacker/algorithms/align.py +184 -80
- shinestacker/algorithms/align_auto.py +13 -11
- shinestacker/algorithms/align_parallel.py +41 -16
- shinestacker/algorithms/base_stack_algo.py +1 -1
- shinestacker/algorithms/noise_detection.py +10 -8
- shinestacker/algorithms/pyramid_tiles.py +1 -1
- shinestacker/algorithms/stack.py +9 -0
- shinestacker/algorithms/stack_framework.py +49 -25
- shinestacker/algorithms/utils.py +5 -1
- shinestacker/algorithms/vignetting.py +16 -3
- shinestacker/app/settings_dialog.py +303 -136
- shinestacker/config/constants.py +10 -5
- shinestacker/config/settings.py +29 -8
- shinestacker/core/core_utils.py +1 -0
- shinestacker/core/exceptions.py +1 -1
- shinestacker/core/framework.py +9 -4
- shinestacker/gui/action_config.py +23 -20
- shinestacker/gui/action_config_dialog.py +107 -64
- shinestacker/gui/gui_images.py +27 -3
- shinestacker/gui/gui_run.py +1 -2
- shinestacker/gui/img/dark/close-round-line-icon.png +0 -0
- shinestacker/gui/img/dark/forward-button-icon.png +0 -0
- shinestacker/gui/img/dark/play-button-round-icon.png +0 -0
- shinestacker/gui/img/dark/plus-round-line-icon.png +0 -0
- shinestacker/gui/img/dark/shinestacker_bkg.png +0 -0
- shinestacker/gui/main_window.py +20 -7
- shinestacker/gui/menu_manager.py +18 -7
- shinestacker/gui/new_project.py +18 -9
- shinestacker/gui/project_controller.py +13 -6
- shinestacker/gui/project_editor.py +12 -2
- shinestacker/gui/project_model.py +4 -4
- shinestacker/gui/tab_widget.py +16 -6
- shinestacker/retouch/adjustments.py +5 -0
- {shinestacker-1.7.0.dist-info → shinestacker-1.8.1.dist-info}/METADATA +35 -39
- {shinestacker-1.7.0.dist-info → shinestacker-1.8.1.dist-info}/RECORD +45 -40
- /shinestacker/gui/img/{close-round-line-icon.png → light/close-round-line-icon.png} +0 -0
- /shinestacker/gui/img/{forward-button-icon.png → light/forward-button-icon.png} +0 -0
- /shinestacker/gui/img/{play-button-round-icon.png → light/play-button-round-icon.png} +0 -0
- /shinestacker/gui/img/{plus-round-line-icon.png → light/plus-round-line-icon.png} +0 -0
- /shinestacker/gui/{ico → img/light}/shinestacker_bkg.png +0 -0
- {shinestacker-1.7.0.dist-info → shinestacker-1.8.1.dist-info}/WHEEL +0 -0
- {shinestacker-1.7.0.dist-info → shinestacker-1.8.1.dist-info}/entry_points.txt +0 -0
- {shinestacker-1.7.0.dist-info → shinestacker-1.8.1.dist-info}/licenses/LICENSE +0 -0
- {shinestacker-1.7.0.dist-info → shinestacker-1.8.1.dist-info}/top_level.txt +0 -0
|
@@ -14,6 +14,9 @@ from .project_model import Project
|
|
|
14
14
|
from .project_editor import ProjectEditor
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
CURRENT_PROJECT_FILE_VERSION = 1
|
|
18
|
+
|
|
19
|
+
|
|
17
20
|
class ProjectController(QObject):
|
|
18
21
|
update_title_requested = Signal()
|
|
19
22
|
refresh_ui_requested = Signal(int, int)
|
|
@@ -162,14 +165,15 @@ class ProjectController(QObject):
|
|
|
162
165
|
if dialog.get_noise_detection():
|
|
163
166
|
job_noise = ActionConfig(
|
|
164
167
|
constants.ACTION_JOB,
|
|
165
|
-
{'name': f'{input_path}-
|
|
168
|
+
{'name': f'{input_path}-noise-job', 'working_path': working_path,
|
|
166
169
|
'input_path': input_path})
|
|
170
|
+
noise_detection_name = f'{input_path}-detect-noise'
|
|
167
171
|
noise_detection = ActionConfig(constants.ACTION_NOISEDETECTION,
|
|
168
|
-
{'name':
|
|
172
|
+
{'name': noise_detection_name})
|
|
169
173
|
job_noise.add_sub_action(noise_detection)
|
|
170
174
|
self.add_job_to_project(job_noise)
|
|
171
175
|
job_params = {
|
|
172
|
-
'name': f'{input_path}-
|
|
176
|
+
'name': f'{input_path}-stack-job',
|
|
173
177
|
'working_path': working_path,
|
|
174
178
|
'input_path': input_path
|
|
175
179
|
}
|
|
@@ -184,7 +188,10 @@ class ProjectController(QObject):
|
|
|
184
188
|
constants.ACTION_COMBO, {'name': preprocess_name})
|
|
185
189
|
if dialog.get_noise_detection():
|
|
186
190
|
mask_noise = ActionConfig(
|
|
187
|
-
constants.ACTION_MASKNOISE,
|
|
191
|
+
constants.ACTION_MASKNOISE,
|
|
192
|
+
{'name': 'mask-noise',
|
|
193
|
+
'noise_mask': os.path.join(noise_detection_name,
|
|
194
|
+
constants.DEFAULT_NOISE_MAP_FILENAME)})
|
|
188
195
|
combo_action.add_sub_action(mask_noise)
|
|
189
196
|
if dialog.get_vignetting_correction():
|
|
190
197
|
vignetting = ActionConfig(
|
|
@@ -251,7 +258,7 @@ class ProjectController(QObject):
|
|
|
251
258
|
self.set_current_file_path(file_path)
|
|
252
259
|
with open(self.current_file_path(), 'r', encoding="utf-8") as file:
|
|
253
260
|
json_obj = json.load(file)
|
|
254
|
-
project = Project.from_dict(json_obj['project'])
|
|
261
|
+
project = Project.from_dict(json_obj['project'], json_obj['version'])
|
|
255
262
|
if project is None:
|
|
256
263
|
raise RuntimeError(f"Project from file {file_path} produced a null project.")
|
|
257
264
|
self.set_enabled_file_open_close_actions_requested.emit(True)
|
|
@@ -313,7 +320,7 @@ class ProjectController(QObject):
|
|
|
313
320
|
def do_save(self, file_path):
|
|
314
321
|
try:
|
|
315
322
|
json_obj = jsonpickle.encode({
|
|
316
|
-
'project': self.project().to_dict(), 'version':
|
|
323
|
+
'project': self.project().to_dict(), 'version': CURRENT_PROJECT_FILE_VERSION
|
|
317
324
|
})
|
|
318
325
|
with open(file_path, 'w', encoding="utf-8") as f:
|
|
319
326
|
f.write(json_obj)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# pylint: disable=C0114, C0115, C0116, R0903, R0904, R1702, R0917, R0913, R0902, E0611, E1131, E1121
|
|
2
2
|
import os
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from PySide6.QtWidgets import QListWidget, QMessageBox, QDialog, QListWidgetItem, QLabel
|
|
5
|
-
|
|
4
|
+
from PySide6.QtWidgets import (QListWidget, QMessageBox, QDialog, QListWidgetItem, QLabel,
|
|
5
|
+
QSizePolicy)
|
|
6
|
+
from PySide6.QtCore import Qt, QObject, Signal, QEvent, QSize
|
|
6
7
|
from .. config.constants import constants
|
|
7
8
|
from .colors import ColorPalette
|
|
8
9
|
from .action_config_dialog import ActionConfigDialog
|
|
@@ -105,6 +106,8 @@ class HandCursorListWidget(QListWidget):
|
|
|
105
106
|
super().__init__(parent)
|
|
106
107
|
self.setMouseTracking(True)
|
|
107
108
|
self.viewport().setMouseTracking(True)
|
|
109
|
+
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
110
|
+
self.setWordWrap(False)
|
|
108
111
|
|
|
109
112
|
def event(self, event):
|
|
110
113
|
if event.type() == QEvent.HoverMove:
|
|
@@ -503,6 +506,13 @@ class ProjectEditor(QObject):
|
|
|
503
506
|
if action.enabled() \
|
|
504
507
|
else f"🚫 <span style='color:#{ColorPalette.DARK_RED.hex()};'>{text}</span>"
|
|
505
508
|
label = QLabel(html_text)
|
|
509
|
+
label.setTextFormat(Qt.RichText)
|
|
510
|
+
label.setWordWrap(False)
|
|
511
|
+
label.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
|
|
512
|
+
label.adjustSize()
|
|
513
|
+
ideal_width = label.sizeHint().width()
|
|
514
|
+
widget_list.setItemWidget(item, label)
|
|
515
|
+
item.setSizeHint(QSize(ideal_width, label.sizeHint().height()))
|
|
506
516
|
widget_list.setItemWidget(item, label)
|
|
507
517
|
|
|
508
518
|
def add_sub_action(self, type_name):
|
|
@@ -62,10 +62,10 @@ class ActionConfig:
|
|
|
62
62
|
return project_dict
|
|
63
63
|
|
|
64
64
|
@classmethod
|
|
65
|
-
def from_dict(cls, data):
|
|
65
|
+
def from_dict(cls, data, version):
|
|
66
66
|
a = ActionConfig(data['type_name'], data['params'])
|
|
67
67
|
if 'sub_actions' in data.keys():
|
|
68
|
-
a.sub_actions = [ActionConfig.from_dict(s) for s in data['sub_actions']]
|
|
68
|
+
a.sub_actions = [ActionConfig.from_dict(s, version) for s in data['sub_actions']]
|
|
69
69
|
for s in a.sub_actions:
|
|
70
70
|
s.parent = a
|
|
71
71
|
return a
|
|
@@ -84,9 +84,9 @@ class Project:
|
|
|
84
84
|
return [j.to_dict() for j in self.jobs]
|
|
85
85
|
|
|
86
86
|
@classmethod
|
|
87
|
-
def from_dict(cls, data):
|
|
87
|
+
def from_dict(cls, data, version):
|
|
88
88
|
p = Project()
|
|
89
|
-
p.jobs = [ActionConfig.from_dict(j) for j in data]
|
|
89
|
+
p.jobs = [ActionConfig.from_dict(j, version) for j in data]
|
|
90
90
|
for j in p.jobs:
|
|
91
91
|
for s in j.sub_actions:
|
|
92
92
|
s.parent = j
|
shinestacker/gui/tab_widget.py
CHANGED
|
@@ -9,8 +9,10 @@ class TabWidgetWithPlaceholder(QWidget):
|
|
|
9
9
|
currentChanged = Signal(int)
|
|
10
10
|
tabCloseRequested = Signal(int)
|
|
11
11
|
|
|
12
|
-
def __init__(self, parent=None):
|
|
12
|
+
def __init__(self, dark_theme, parent=None):
|
|
13
13
|
super().__init__(parent)
|
|
14
|
+
self.script_dir = os.path.dirname(__file__)
|
|
15
|
+
self.dark_theme = dark_theme
|
|
14
16
|
self.main_layout = QVBoxLayout(self)
|
|
15
17
|
self.main_layout.setContentsMargins(0, 0, 0, 0)
|
|
16
18
|
self.stacked_widget = QStackedWidget()
|
|
@@ -19,7 +21,15 @@ class TabWidgetWithPlaceholder(QWidget):
|
|
|
19
21
|
self.stacked_widget.addWidget(self.tab_widget)
|
|
20
22
|
self.placeholder = QLabel()
|
|
21
23
|
self.placeholder.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
22
|
-
|
|
24
|
+
self.set_bkg_icon()
|
|
25
|
+
self.stacked_widget.addWidget(self.placeholder)
|
|
26
|
+
self.tab_widget.currentChanged.connect(self._on_current_changed)
|
|
27
|
+
self.tab_widget.tabCloseRequested.connect(self._on_tab_close_requested)
|
|
28
|
+
self.update_placeholder_visibility()
|
|
29
|
+
|
|
30
|
+
def set_bkg_icon(self):
|
|
31
|
+
icon_dir = 'dark' if self.dark_theme else 'light'
|
|
32
|
+
icon_path = os.path.join(self.script_dir, f"img/{icon_dir}/shinestacker_bkg.png")
|
|
23
33
|
if os.path.exists(icon_path):
|
|
24
34
|
pixmap = QPixmap(icon_path)
|
|
25
35
|
pixmap = pixmap.scaled(250, 250, Qt.AspectRatioMode.KeepAspectRatio,
|
|
@@ -27,10 +37,10 @@ class TabWidgetWithPlaceholder(QWidget):
|
|
|
27
37
|
self.placeholder.setPixmap(pixmap)
|
|
28
38
|
else:
|
|
29
39
|
self.placeholder.setText("Run logs will appear here.")
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
self.
|
|
33
|
-
self.
|
|
40
|
+
|
|
41
|
+
def change_theme(self, dark_theme):
|
|
42
|
+
self.dark_theme = dark_theme
|
|
43
|
+
self.set_bkg_icon()
|
|
34
44
|
|
|
35
45
|
def _on_current_changed(self, index):
|
|
36
46
|
self.currentChanged.emit(index)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# pylint: disable=C0114, C0115, C0116, E0611, W0221, R0913, R0917, R0902, R0914, E1101
|
|
2
|
+
from abc import abstractmethod
|
|
2
3
|
import math
|
|
3
4
|
import cv2
|
|
4
5
|
from .base_filter import BaseFilter
|
|
@@ -24,6 +25,10 @@ class GammaSCurveFilter(BaseFilter):
|
|
|
24
25
|
self.lumi_slider = None
|
|
25
26
|
self.contrast_slider = None
|
|
26
27
|
|
|
28
|
+
@abstractmethod
|
|
29
|
+
def apply(self, image, *params):
|
|
30
|
+
pass
|
|
31
|
+
|
|
27
32
|
def setup_ui(self, dlg, layout, do_preview, restore_original, **kwargs):
|
|
28
33
|
dlg.setWindowTitle(self.window_title)
|
|
29
34
|
dlg.setMinimumWidth(600)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shinestacker
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.1
|
|
4
4
|
Summary: ShineStacker
|
|
5
5
|
Author-email: Luca Lista <luka.lista@gmail.com>
|
|
6
6
|
License-Expression: LGPL-3.0
|
|
@@ -30,11 +30,9 @@ Provides-Extra: dev
|
|
|
30
30
|
Requires-Dist: pytest; extra == "dev"
|
|
31
31
|
Dynamic: license-file
|
|
32
32
|
|
|
33
|
-
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/src/shinestacker/gui/ico/shinestacker.png' width="150" referrerpolicy="no-referrer" alt="Shine Stacker Logo">
|
|
34
|
-
|
|
35
33
|
# Shine Stacker
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
Focus Stacking Processing Framework and GUI designed for macro photographers, microscopists, and researchers who need precise control and reproducible stacking results.
|
|
38
36
|
|
|
39
37
|
[](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml)
|
|
40
38
|
[](https://pypi.org/project/shinestacker/)
|
|
@@ -45,60 +43,55 @@ Dynamic: license-file
|
|
|
45
43
|
[](https://shinestacker.readthedocs.io/en/latest/?badge=latest)
|
|
46
44
|
[](https://www.gnu.org/licenses/lgpl-3.0)
|
|
47
45
|
[](https://pepy.tech/projects/shinestacker)
|
|
48
|
-
|
|
49
|
-
<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">
|
|
50
|
-
|
|
51
|
-
<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">
|
|
52
|
-
|
|
53
|
-
> **Focus stacking** for microscopy, macro photography, and computational imaging
|
|
46
|
+
<center><img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/src/shinestacker/gui/ico/shinestacker.png' width="150" referrerpolicy="no-referrer" alt="Shine Stacker Logo"></center>
|
|
54
47
|
|
|
55
48
|
## Key Features
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
49
|
+
- 🪟 **Cross-Platform GUI**: Native app built with Qt6, available for Windows, macOS, and Linux.
|
|
50
|
+
- 🚀 **Batch Processing**: Automatically align, balance, and stack hundreds of images — perfect for macro or microscopy datasets.
|
|
51
|
+
- 🧩 **Modular Architecture**: Combine configurable modules for alignment, normalization, and blending to build custom workflows.
|
|
52
|
+
- 🖌️ **Retouch Editor**: Interactively refine your stacked image by painting in details from individual frames.
|
|
53
|
+
- 📊 **Jupyter & Python Integration**: Use Shine Stacker as a library inside your Python or Jupyter workflows.
|
|
54
|
+
|
|
55
|
+
<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">
|
|
60
56
|
|
|
61
57
|
## Interactive GUI
|
|
62
58
|
|
|
63
|
-
The
|
|
59
|
+
The graphical interface makes complex stacking tasks simple:
|
|
60
|
+
- **Project View** – Configure, preview, and run stacking workflows with optional intermediate results.
|
|
61
|
+
- **Retouch View** – Manually refine the final image by blending details from selected frames and applying filters.
|
|
64
62
|
|
|
65
|
-
|
|
63
|
+
Ideal for users who want the power of scripting and the comfort of a modern UI.
|
|
66
64
|
|
|
67
|
-
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/
|
|
65
|
+
<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">
|
|
68
66
|
|
|
69
|
-
|
|
67
|
+
## Get Started
|
|
70
68
|
|
|
71
|
-
|
|
69
|
+
- 📦 [Install via PyPI](https://pypi.org/project/shinestacker/)
|
|
70
|
+
- 💻 [Run the GUI app](https://shinestacker.readthedocs.io/en/latest/gui.html)
|
|
71
|
+
- 🧠 [Reference](https://shinestacker.readthedocs.io/en/)
|
|
72
|
+
- 🐛 [Report an issue](https://github.com/lucalista/shinestacker/issues)
|
|
72
73
|
|
|
73
74
|
## Resources
|
|
74
75
|
|
|
75
76
|
🌍 [Website on WordPress](https://shinestacker.wordpress.com) • 📖 [Main documentation](https://shinestacker.readthedocs.io) • 📝 [Changelog](https://github.com/lucalista/shinestacker/blob/main/CHANGELOG.md)
|
|
76
77
|
|
|
77
|
-
##
|
|
78
|
-
|
|
79
|
-
**The following note is only relevant if you download the application as compressed archive from the [release page](https://github.com/lucalista/shinestacker/releases).**
|
|
78
|
+
## Installation
|
|
80
79
|
|
|
81
|
-
|
|
80
|
+
See the [main documentation](https://github.com/lucalista/shinestacker/blob/main/docs/main.md) for detailed installation instructions.
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
**Platform notes:**
|
|
83
|
+
- **Windows:** If you download the installer or ZIP archive, you may need to whitelist the app in your antivirus software.
|
|
84
|
+
- **macOS:** See the [installation note for macOS users](https://github.com/lucalista/shinestacker/blob/main/docs/macos-install.md).
|
|
84
85
|
|
|
85
|
-
1. Download the compressed archive ```shinestacker-macos.tar.gz``` in your ```Download``` folder.
|
|
86
|
-
2. Double-click the archive to uncompress it. You will find a new folder ```shinestacker```.
|
|
87
|
-
3. Open a terminal (*Applications > Utilities > Terminal*)
|
|
88
|
-
4. Type the folliwng command on the terminal (assuming you have expanded the ```tar.gz``` under ```Downloads```):
|
|
89
|
-
```bash
|
|
90
|
-
xattr -cr ~/Downloads/shinestacker/shinestacker.app
|
|
91
|
-
```
|
|
92
|
-
5. Now you can double-click the Sine Stacker icon app in the ```shiestacker``` folder and it should run.
|
|
93
86
|
|
|
94
|
-
|
|
87
|
+
## Acknowledgements & References
|
|
95
88
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
## Resources
|
|
89
|
+
The first version of the core focus stack algorithm was inspired by the
|
|
90
|
+
[Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation
|
|
91
|
+
by Sami Jawhar, used under permission. The implementation in the latest releases
|
|
92
|
+
was rewritten from the original code.
|
|
101
93
|
|
|
94
|
+
Key references:
|
|
102
95
|
* [Pyramid Methods in Image Processing](https://www.researchgate.net/publication/246727904_Pyramid_Methods_in_Image_Processing), E. H. Adelson, C. H. Anderson, J. R. Bergen, P. J. Burt, J. M. Ogden, RCA Engineer, 29-6, Nov/Dec 1984
|
|
103
96
|
Pyramid methods in image processing
|
|
104
97
|
* [A Multi-focus Image Fusion Method Based on Laplacian Pyramid](http://www.jcomputers.us/vol6/jcp0612-07.pdf), Wencheng Wang, Faliang Chang, Journal of Computers 6 (12), 2559, December 2011
|
|
@@ -108,7 +101,6 @@ Pyramid methods in image processing
|
|
|
108
101
|
<img src="https://www.gnu.org/graphics/lgplv3-147x51.png" alt="LGPL 3 logo">
|
|
109
102
|
|
|
110
103
|
- **Code**: The software is provided as is under the [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html). See [LICENSE](https://github.com/lucalista/shinestacker/blob/main/LICENSE) for details.
|
|
111
|
-
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/src/shinestacker/gui/ico/shinestacker.png' width="150" referrerpolicy="no-referrer" alt="Shine Stacker Logo">
|
|
112
104
|
|
|
113
105
|
- **Logo**: The Shine Stacker logo was designed by [Alessandro Lista](https://linktr.ee/alelista). Copyright © Alessandro Lista. All rights reserved. The logo is not covered by the LGPL-3.0 license of this project.
|
|
114
106
|
|
|
@@ -118,3 +110,7 @@ Pyramid methods in image processing
|
|
|
118
110
|
*Created with Shine Stacker – https://github.com/lucalista/shinestacker*
|
|
119
111
|
|
|
120
112
|
This is not mandatory, but highly appreciated.
|
|
113
|
+
---
|
|
114
|
+
> Developed and maintained by [Luca Lista](https://github.com/lucalista).
|
|
115
|
+
> 💡 Contributions, feedback, and feature suggestions are warmly welcome.
|
|
116
|
+
> If you enjoy Shine Stacker, consider giving it a ⭐️ on GitHub — it really helps visibility!
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
shinestacker/__init__.py,sha256=uq2fjAw2z_6TpH3mOcWFZ98GoEPRsNhTAK8N0MMm_e8,448
|
|
2
|
-
shinestacker/_version.py,sha256=
|
|
2
|
+
shinestacker/_version.py,sha256=VeCo3jG4eMq5JgUgBBkmfX0RYN_MfWUdUGiQ16h2kPg,21
|
|
3
3
|
shinestacker/algorithms/__init__.py,sha256=1FwVJ3w9GGbFFkjYJRUedTvcdE4j0ieSgaH9RC9iCY4,877
|
|
4
|
-
shinestacker/algorithms/align.py,sha256=
|
|
5
|
-
shinestacker/algorithms/align_auto.py,sha256=
|
|
6
|
-
shinestacker/algorithms/align_parallel.py,sha256=
|
|
4
|
+
shinestacker/algorithms/align.py,sha256=840SLh38JePGQv9vgG2H6jHkgHSAYzSpbNDDTxV5ghg,37915
|
|
5
|
+
shinestacker/algorithms/align_auto.py,sha256=DsHuAkFXSHbtFwp6XRaV3Sy1LGcUZWYAFijJXWrd1Bo,3833
|
|
6
|
+
shinestacker/algorithms/align_parallel.py,sha256=TcoIRBqrEbxDwOPOo1SinSGwW3M3cq3Agx6o8Sf9ILg,19215
|
|
7
7
|
shinestacker/algorithms/balance.py,sha256=aoqnc1u5A2C3R7fKaOoKnzudRiOT8GRIu4LEP-uzyZQ,24053
|
|
8
|
-
shinestacker/algorithms/base_stack_algo.py,sha256=
|
|
8
|
+
shinestacker/algorithms/base_stack_algo.py,sha256=mqCCRufLc9k5fZV5Su41AsN1ecHrZJzp1xtpmbJ7wb0,2669
|
|
9
9
|
shinestacker/algorithms/corrections.py,sha256=DrfLM33D20l4svuuBtoOiH-KGUH_BL1mAV7mHCA_nGA,1094
|
|
10
10
|
shinestacker/algorithms/denoise.py,sha256=GL3Z4_6MHxSa7Wo4ZzQECZS87tHBFqO0sIVF_jPuYQU,426
|
|
11
11
|
shinestacker/algorithms/depth_map.py,sha256=nRBrZQWbdUqFOtYMEQx9UNdnybrBTeAOr1eV91FlN8U,5611
|
|
12
12
|
shinestacker/algorithms/exif.py,sha256=SM4ZDDe8hCJ3xY6053FNndOiwzEStzdp0WrXurlcHVc,9429
|
|
13
13
|
shinestacker/algorithms/multilayer.py,sha256=EEMDr2NlCU9DCFO5ykbBrY-2q9oBUD0-ctm7x0IXU5U,9911
|
|
14
|
-
shinestacker/algorithms/noise_detection.py,sha256=
|
|
14
|
+
shinestacker/algorithms/noise_detection.py,sha256=SbWcxSPZIxnThXITAe7koPLKhQZ_gciQby50u3QfkGs,9464
|
|
15
15
|
shinestacker/algorithms/pyramid.py,sha256=Z7tlp8Hh3ploAXJCr0VNe33d8H9GNrlqHXq_LapgRwo,8205
|
|
16
16
|
shinestacker/algorithms/pyramid_auto.py,sha256=fl_jXNYLWsBiX0M0UghzCLqai0SGXlmKYHU7Z9SUYSo,6173
|
|
17
|
-
shinestacker/algorithms/pyramid_tiles.py,sha256=
|
|
17
|
+
shinestacker/algorithms/pyramid_tiles.py,sha256=t04_06oYF6QkSSyFQEivHh-GDTska2dQEmfCYoscy-c,12216
|
|
18
18
|
shinestacker/algorithms/sharpen.py,sha256=h7PMJBYxucg194Usp_6pvItPUMFYbT-ebAc_-7XBFUw,949
|
|
19
|
-
shinestacker/algorithms/stack.py,sha256=
|
|
20
|
-
shinestacker/algorithms/stack_framework.py,sha256=
|
|
21
|
-
shinestacker/algorithms/utils.py,sha256=
|
|
22
|
-
shinestacker/algorithms/vignetting.py,sha256=
|
|
19
|
+
shinestacker/algorithms/stack.py,sha256=VvYo6w01sGbMIWS3w_4fVz6k7qOTpuEREXTP4kze6B0,5738
|
|
20
|
+
shinestacker/algorithms/stack_framework.py,sha256=YEuaxDqs3gytZMUnub69gcuv5CnbwU3cLxxPQj6HsXQ,14612
|
|
21
|
+
shinestacker/algorithms/utils.py,sha256=VJFOT-OBtDe5ds64VgwyZKa8AX1N91SSJlsgUVC9vMs,12303
|
|
22
|
+
shinestacker/algorithms/vignetting.py,sha256=KFLPbBv8EAKB5PpO4QIqMbTLEufg-lvxOGkVkiOSEqI,10855
|
|
23
23
|
shinestacker/algorithms/white_balance.py,sha256=PMKsBtxOSn5aRr_Gkx1StHS4eN6kBN2EhNnhg4UG24g,501
|
|
24
24
|
shinestacker/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
25
|
shinestacker/app/about_dialog.py,sha256=pkH7nnxUP8yc0D3vRGd1jRb5cwi1nDVbQRk_OC9yLk8,4144
|
|
@@ -30,53 +30,58 @@ shinestacker/app/main.py,sha256=c9_rax1eemOfkJqWV7tT7-ZkEBkqz6n4kBST8iXsjD4,1066
|
|
|
30
30
|
shinestacker/app/open_frames.py,sha256=bsu32iJSYJQLe_tQQbvAU5DuMDVX6MRuNdE7B5lojZc,1488
|
|
31
31
|
shinestacker/app/project.py,sha256=nwvXllD2FBLQ4ChePQdIGVug46Wh2ubjrJ0sC7klops,2596
|
|
32
32
|
shinestacker/app/retouch.py,sha256=8XcYMv7-feG6yxNCpvlijZQRPlhmRK0OfZO5MuBju-0,2552
|
|
33
|
-
shinestacker/app/settings_dialog.py,sha256=
|
|
33
|
+
shinestacker/app/settings_dialog.py,sha256=x4-mYEUcB1I9SoQmzDpxFzfLI5JU0hbeqmIydbUWylQ,13670
|
|
34
34
|
shinestacker/config/__init__.py,sha256=aXxi-LmAvXd0daIFrVnTHE5OCaYeK1uf1BKMr7oaXQs,197
|
|
35
35
|
shinestacker/config/app_config.py,sha256=rM1Rndk1GDa5c0AhcVNEN9zSAzxPZixzQYfjODbJUwE,771
|
|
36
36
|
shinestacker/config/config.py,sha256=eBko2D3ADhLTIm9X6hB_a_WsIjwgfE-qmBVkhP1XSvc,1636
|
|
37
|
-
shinestacker/config/constants.py,sha256=
|
|
37
|
+
shinestacker/config/constants.py,sha256=fdZ8qp4S5KM_MfXnLCOTnHemNQMcHEio-VatGkDH9-E,8530
|
|
38
38
|
shinestacker/config/gui_constants.py,sha256=PNxzwmVEppJ2mV_vwp68NhWzJOEitVy1Pk9SwSmRsho,2882
|
|
39
|
-
shinestacker/config/settings.py,sha256=
|
|
39
|
+
shinestacker/config/settings.py,sha256=jdRMJRT6AzO-dnvmOCwEGURsGBt36ILH-xszNIvE0ew,4845
|
|
40
40
|
shinestacker/core/__init__.py,sha256=IUEIx6SQ3DygDEHN3_E6uKpHjHtUa4a_U_1dLd_8yEU,484
|
|
41
41
|
shinestacker/core/colors.py,sha256=kr_tJA1iRsdck2JaYDb2lS-codZ4Ty9gdu3kHfiWvuM,1340
|
|
42
|
-
shinestacker/core/core_utils.py,sha256=
|
|
43
|
-
shinestacker/core/exceptions.py,sha256=
|
|
44
|
-
shinestacker/core/framework.py,sha256=
|
|
42
|
+
shinestacker/core/core_utils.py,sha256=PYrV5asW-_L_AavPlk6p63UqzuQGrm55hwkRzmaaCd0,1424
|
|
43
|
+
shinestacker/core/exceptions.py,sha256=67XFH0zqaqHihVdvrmcBLTRudzVbxSkqYe7lbXdHWB8,1618
|
|
44
|
+
shinestacker/core/framework.py,sha256=i-_4v--ZtimmlPUs2DmkEVvbsvEDZmbCmOtMVfCxwwU,11109
|
|
45
45
|
shinestacker/core/logging.py,sha256=pN4FGcHwI5ouJKwCVoDWQx_Tg3t84mmPh0xhqszDDkw,3111
|
|
46
46
|
shinestacker/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
-
shinestacker/gui/action_config.py,sha256=
|
|
48
|
-
shinestacker/gui/action_config_dialog.py,sha256=
|
|
47
|
+
shinestacker/gui/action_config.py,sha256=OWW32h55OTvM6lbfJc3ZhPoa0vVEvsH63iCbTWo6r6E,25843
|
|
48
|
+
shinestacker/gui/action_config_dialog.py,sha256=GYOnTXoEjHHWMS5RECaqtkMMI37OjkP6W5WXPKjYjwE,40727
|
|
49
49
|
shinestacker/gui/base_form_dialog.py,sha256=KAUQNtmJazttmOIe4E4pFifbtvcByTAhtCmcIYeA4UE,766
|
|
50
50
|
shinestacker/gui/colors.py,sha256=-HaFprDuzRSKjXoZfX1rdOuvawQAkazqdgLBEiZcFII,1476
|
|
51
51
|
shinestacker/gui/config_dialog.py,sha256=yt3nvh0HPHQuCn3AFlzlIHUJnnxcz-Rrw3W3jS9ZYiE,3447
|
|
52
52
|
shinestacker/gui/flow_layout.py,sha256=3yBU_z7VtvHKpx1H97CHVd81eq9pe1Dcja2EZBGGKcI,3791
|
|
53
53
|
shinestacker/gui/folder_file_selection.py,sha256=IYWfZQFkoD5iO7zJ7BxVVDP9F3Dc0EXLILAhL4q-Cb8,4117
|
|
54
|
-
shinestacker/gui/gui_images.py,sha256=
|
|
54
|
+
shinestacker/gui/gui_images.py,sha256=KxGBFLL2ztfNmvL4pconi3z5HJCoD2HXxpYZP70aUfM,6803
|
|
55
55
|
shinestacker/gui/gui_logging.py,sha256=kiZcrC2AFYCWgPZo0O5SKw-E5cFrezwf4anS3HjPuNw,8168
|
|
56
|
-
shinestacker/gui/gui_run.py,sha256=
|
|
57
|
-
shinestacker/gui/main_window.py,sha256=
|
|
58
|
-
shinestacker/gui/menu_manager.py,sha256=
|
|
59
|
-
shinestacker/gui/new_project.py,sha256=
|
|
60
|
-
shinestacker/gui/project_controller.py,sha256=
|
|
56
|
+
shinestacker/gui/gui_run.py,sha256=38ke2Zq7KfQBZDNCzfw6RVIUdDTElLKf-tawBarlWyw,15684
|
|
57
|
+
shinestacker/gui/main_window.py,sha256=VYGX-w-A8sy1zsQAJEfLpImax8oB-inx_nZ2XofDEBQ,25777
|
|
58
|
+
shinestacker/gui/menu_manager.py,sha256=mS-pRMymd1yYimbr6Z5YXjMA5AsNuaNcezs8MYWF2DU,12364
|
|
59
|
+
shinestacker/gui/new_project.py,sha256=gvFNToDqLxWbgGBJ19u_2Tn_DlfXTVWQ5wE0dHErXL0,16723
|
|
60
|
+
shinestacker/gui/project_controller.py,sha256=h2x7Z1MFKXQGB4dGmdLcXQgcDTtId9RMi3m-4pSli2Y,16963
|
|
61
61
|
shinestacker/gui/project_converter.py,sha256=Gmna0HwbvACcXiX74TaQYumif8ZV8sZ2APLTMM-L1mU,7436
|
|
62
|
-
shinestacker/gui/project_editor.py,sha256=
|
|
63
|
-
shinestacker/gui/project_model.py,sha256=
|
|
62
|
+
shinestacker/gui/project_editor.py,sha256=9KEH-CkIbK_yLKRo184C08uYXQ9_aqepEGQrKRqhfUg,25991
|
|
63
|
+
shinestacker/gui/project_model.py,sha256=9Mr3Y87Pj8J-mSkgn9NexaxzZkB39zkIGG5zzeUojB0,4869
|
|
64
64
|
shinestacker/gui/recent_file_manager.py,sha256=010bciuirKLiVCfOAKs0uFlB3iUjHNBlPX_9K2vH5j0,2916
|
|
65
65
|
shinestacker/gui/select_path_widget.py,sha256=HSwgSr702w5Et4c-6nkRXnIpm1KFqKJetAF5xQNa5zI,1017
|
|
66
66
|
shinestacker/gui/sys_mon.py,sha256=zU41YYVeqQ1-v6oGIh2_BFzQWq87keN-398Wdm59-Nk,3526
|
|
67
|
-
shinestacker/gui/tab_widget.py,sha256=
|
|
67
|
+
shinestacker/gui/tab_widget.py,sha256=rS4OCJMKjjE0yZxVEzohZo7wVlPnTt_BExbh3xWOlio,3122
|
|
68
68
|
shinestacker/gui/time_progress_bar.py,sha256=7_sllrQgayjRh__mwJ0-4lghXIakuRAx8wWucJ6olYs,3028
|
|
69
69
|
shinestacker/gui/ico/shinestacker.icns,sha256=lKmyIUBTjpMQ6Cajcov6WA5neAbZS9-JN5ca02nCz5I,204834
|
|
70
70
|
shinestacker/gui/ico/shinestacker.ico,sha256=8IMRk-toObWUz8iDXA-zHBWQ8Ps3vXN5u5ZEyw7sP3c,109613
|
|
71
71
|
shinestacker/gui/ico/shinestacker.png,sha256=VybGY-nig_-wMW8g_uImGxRYvcnltWcAVEPSX6AZUHM,22448
|
|
72
72
|
shinestacker/gui/ico/shinestacker.svg,sha256=r8jx5aiIT9K70MRP0ANWniFE0ctRCqH7LMQ7vcGJ8ss,6571
|
|
73
|
-
shinestacker/gui/
|
|
74
|
-
shinestacker/gui/img/
|
|
75
|
-
shinestacker/gui/img/
|
|
76
|
-
shinestacker/gui/img/
|
|
77
|
-
shinestacker/gui/img/
|
|
73
|
+
shinestacker/gui/img/dark/close-round-line-icon.png,sha256=kq3xxlLpig4t2yBJ_MaSN8zW11YyX7gHlUx6a1L7RV4,13819
|
|
74
|
+
shinestacker/gui/img/dark/forward-button-icon.png,sha256=o26xL4ep0W9Upe6oYoSR4pBZgkZU_eU2UGSczeWOkyM,8102
|
|
75
|
+
shinestacker/gui/img/dark/play-button-round-icon.png,sha256=jAaTZGMsvjWBKMXBANLMGRkQx_tUjBOiEX6oKTmhU5w,7745
|
|
76
|
+
shinestacker/gui/img/dark/plus-round-line-icon.png,sha256=S52m17SVjCxZJECSioDrTInSVgXgVoWYfHqMvlvy1zE,13369
|
|
77
|
+
shinestacker/gui/img/dark/shinestacker_bkg.png,sha256=0kgFDH8lF_ttyhILRJAOn71hbpU-rO4W2DYH05Ib_XY,9748
|
|
78
|
+
shinestacker/gui/img/light/close-round-line-icon.png,sha256=9HZwCjgni1s_JGUPUb_MoOfoe4tRZgM5OWzk92XFZlE,8019
|
|
79
|
+
shinestacker/gui/img/light/forward-button-icon.png,sha256=lNw86T4TOEd_uokHYF8myGSGUXzdsHvmDAjlbE18Pgo,4788
|
|
80
|
+
shinestacker/gui/img/light/play-button-round-icon.png,sha256=9j6Ks9mOGa-2cXyRFpimepAAvSaHzqJKBfxShRb4_dE,4595
|
|
81
|
+
shinestacker/gui/img/light/plus-round-line-icon.png,sha256=LS068Hlu-CeBvJuB3dwwdJg1lZq6D5MUIv53lu1yKJA,7534
|
|
82
|
+
shinestacker/gui/img/light/shinestacker_bkg.png,sha256=C91Ek4bm8hPcit4JUac8FAjRTQsHfiKIKPTZMweHKqo,10462
|
|
78
83
|
shinestacker/retouch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
|
-
shinestacker/retouch/adjustments.py,sha256=
|
|
84
|
+
shinestacker/retouch/adjustments.py,sha256=LGbsUnPF5CJaJ5U_5Fmk5LoNGW0STttrFUcBjWN06As,3928
|
|
80
85
|
shinestacker/retouch/base_filter.py,sha256=o_OkJbdD3jOGY--_sGL1_WqAMQI-QHGw-EEYxGhXOaQ,13976
|
|
81
86
|
shinestacker/retouch/brush.py,sha256=dzD2FzSpBIPdJRmTZobcrQ1FrVd3tF__ZPnUplNE72s,357
|
|
82
87
|
shinestacker/retouch/brush_gradient.py,sha256=F5SFhyzl8YTMqjJU3jK8BrIlLCYLUvITd5wz3cQE4xk,1453
|
|
@@ -104,9 +109,9 @@ shinestacker/retouch/unsharp_mask_filter.py,sha256=SO-6ZgPPDAO9em_MMefVvvSvt01-2
|
|
|
104
109
|
shinestacker/retouch/view_strategy.py,sha256=jZxB_vX3_0notH0ClxKkLzbdtx4is3vQiYoIP-sDv3M,30216
|
|
105
110
|
shinestacker/retouch/vignetting_filter.py,sha256=M7PZGPdVSq4bqo6wkEznrILMIG3-mTT7iwpgK4Hieyg,3794
|
|
106
111
|
shinestacker/retouch/white_balance_filter.py,sha256=UaH4yxG3fU4vPutBAkV5oTXIQyUTN09x0uTywAzv3sY,8286
|
|
107
|
-
shinestacker-1.
|
|
108
|
-
shinestacker-1.
|
|
109
|
-
shinestacker-1.
|
|
110
|
-
shinestacker-1.
|
|
111
|
-
shinestacker-1.
|
|
112
|
-
shinestacker-1.
|
|
112
|
+
shinestacker-1.8.1.dist-info/licenses/LICENSE,sha256=pWgb-bBdsU2Gd2kwAXxketnm5W_2u8_fIeWEgojfrxs,7651
|
|
113
|
+
shinestacker-1.8.1.dist-info/METADATA,sha256=3Lq1O-DEp4lKM1EcwARqdZ6T92cjXw5TXerHxIC30Ws,6881
|
|
114
|
+
shinestacker-1.8.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
115
|
+
shinestacker-1.8.1.dist-info/entry_points.txt,sha256=SY6g1LqtMmp23q1DGwLUDT_dhLX9iss8DvWkiWLyo_4,166
|
|
116
|
+
shinestacker-1.8.1.dist-info/top_level.txt,sha256=MhijwnBVX5psfsyX8JZjqp3SYiWPsKe69f3Gnyze4Fw,13
|
|
117
|
+
shinestacker-1.8.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|