shinestacker 0.2.1__tar.gz → 0.2.2__tar.gz
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-0.2.2/.coverage +0 -0
- shinestacker-0.2.2/.coveragerc +5 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/.github/workflows/ci-multiplatform.yml +9 -3
- shinestacker-0.2.2/.readthedocs.yaml +22 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/CHANGELOG.md +20 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/PKG-INFO +8 -5
- {shinestacker-0.2.1 → shinestacker-0.2.2}/README.md +5 -4
- {shinestacker-0.2.1 → shinestacker-0.2.2}/docs/alignment.md +3 -1
- shinestacker-0.2.2/docs/api.md +10 -0
- shinestacker-0.2.2/docs/conf.py +42 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/docs/gui.md +5 -5
- shinestacker-0.2.2/docs/index.md +22 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/docs/job.md +2 -2
- {shinestacker-0.2.1 → shinestacker-0.2.2}/docs/main.md +11 -10
- shinestacker-0.2.2/docs/requirements.txt +3 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/pyproject.toml +4 -0
- shinestacker-0.2.2/src/shinestacker/__init__.py +16 -0
- shinestacker-0.2.2/src/shinestacker/_version.py +1 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/__init__.py +5 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/align.py +0 -1
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/core_utils.py +1 -1
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/app/main.py +0 -1
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/app/project.py +0 -1
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/app/retouch.py +0 -1
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/config/__init__.py +2 -0
- shinestacker-0.2.2/src/shinestacker/core/__init__.py +11 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/new_project.py +0 -1
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/project_editor.py +0 -1
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/exif_data.py +0 -1
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/shortcuts_help.py +0 -1
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker.egg-info/PKG-INFO +8 -5
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker.egg-info/SOURCES.txt +12 -1
- shinestacker-0.2.2/tests/test_0002_config.py +60 -0
- shinestacker-0.2.2/tests/test_0006_exceptions.py +99 -0
- shinestacker-0.2.2/tests/test_0011_core_utils.py +105 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0020_noise_detection.py +5 -4
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0030_align.py +17 -5
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0032_align_methods.py +11 -3
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0040_balance.py +6 -6
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0050_align_balance.py +4 -4
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0060_stack.py +4 -4
- shinestacker-0.2.2/tests/test_0061_depth_map.py +84 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0070_multilayer.py +23 -9
- shinestacker-0.2.2/tests/test_0080_exif.py +220 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0090_vignetting.py +4 -2
- shinestacker-0.2.2/tests/test_0091_vignetting_algo.py +127 -0
- shinestacker-0.2.1/sandbox/test_alignment_multiple.py +0 -124
- shinestacker-0.2.1/src/shinestacker/__init__.py +0 -3
- shinestacker-0.2.1/src/shinestacker/_version.py +0 -1
- shinestacker-0.2.1/src/shinestacker/core/__init__.py +0 -5
- shinestacker-0.2.1/tests/test_0080_exif.py +0 -90
- {shinestacker-0.2.1 → shinestacker-0.2.2}/.flake8 +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/.github/workflows/pypi-publish.yml +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/.github/workflows/release.yml +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/.gitignore +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/LICENSE +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/docs/balancing.md +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/docs/focus_stacking.md +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/docs/multilayer.md +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/docs/noise.md +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/docs/vignetting.md +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/balance-only.fsp +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/complete-project.fsp +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/focus-stack-1.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/focus-stack-2.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-jpg/0000.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-jpg/0001.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-jpg/0002.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-jpg/0003.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-jpg/0004.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-jpg/0005.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-noise/0001.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-noise/0002.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-noise/0003.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-noise/0004.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-noise/0005.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-noise/0006.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-tif/0000.tif +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-tif/0001.tif +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-tif/0002.tif +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-tif/0003.tif +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-tif/0004.tif +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-tif/0005.tif +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-vignetted/vig-0000.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-vignetted/vig-0001.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-vignetted/vig-0002.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/input/img-vignetted/vig-0003.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/stack-comparison.fsp +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/stack-from-frames.fsp +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/examples/vignetting.fsp +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/img/flies.gif +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/img/flies_stack.jpg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/img/flow-diagram.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/img/gui-finder.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/img/gui-project-new.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/img/gui-project-run.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/img/gui-retouch.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/scripts/build_release.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/scripts/validate-tomli.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/setup.cfg +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/balance.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/depth_map.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/exif.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/multilayer.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/noise_detection.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/pyramid.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/stack.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/stack_framework.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/utils.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/algorithms/vignetting.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/app/__init__.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/app/about_dialog.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/app/app_config.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/app/gui_utils.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/app/help_menu.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/app/open_frames.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/config/config.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/config/constants.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/config/gui_constants.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/core/colors.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/core/core_utils.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/core/exceptions.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/core/framework.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/core/logging.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/__init__.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/action_config.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/actions_window.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/colors.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/gui_images.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/gui_logging.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/gui_run.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/ico/focus_stack_bkg.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/ico/shinestacker.icns +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/ico/shinestacker.ico +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/ico/shinestacker.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/img/close-round-line-icon.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/img/forward-button-icon.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/img/play-button-round-icon.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/img/plus-round-line-icon.png +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/main_window.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/project_converter.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/gui/project_model.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/__init__.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/brush.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/brush_controller.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/brush_preview.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/file_loader.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/image_editor.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/image_editor_ui.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/image_viewer.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker/retouch/undo_manager.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker.egg-info/dependency_links.txt +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker.egg-info/entry_points.txt +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker.egg-info/requires.txt +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/src/shinestacker.egg-info/top_level.txt +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-align-balance.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-align.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-balance.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-exif.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-job.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-logging.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-multilayer.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-noise-detection.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-stack.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test-vignetting.ipynb +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0000_logging.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0001_colors.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0005_make_test_img.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0010_job.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_0031_align_precision.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_1000_brush_mask.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_1010_gui.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_1020_gui_images.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_1030_gui_logging.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_1040_action_config.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_1050_project_converter.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_1060_gui_run.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_1070_project_editor.py +0 -0
- {shinestacker-0.2.1 → shinestacker-0.2.2}/tests/test_1080_actions_window.py +0 -0
|
Binary file
|
|
@@ -30,10 +30,16 @@ jobs:
|
|
|
30
30
|
|
|
31
31
|
- name: Install dependencies
|
|
32
32
|
run: |
|
|
33
|
-
python -m pip install --upgrade pip setuptools
|
|
33
|
+
python -m pip install --upgrade pip setuptools pytest-cov
|
|
34
34
|
pip install -e .[dev]
|
|
35
35
|
|
|
36
36
|
- name: Run non-GUI tests (test_00*.py)
|
|
37
|
-
working-directory: tests
|
|
38
37
|
run: >
|
|
39
|
-
python3 -c "import glob, pytest, sys; sys.exit(pytest.main(glob.glob('test_00*.py') + ['-v', '--disable-warnings']))"
|
|
38
|
+
python3 -c "import glob, pytest, sys; sys.exit(pytest.main(glob.glob('tests/test_00*.py') + ['-v', '--disable-warnings', '--cov=shinestacker', '--cov-report=xml']))"
|
|
39
|
+
|
|
40
|
+
- name: Upload coverage to Codecov
|
|
41
|
+
if: matrix.os == 'ubuntu-latest'
|
|
42
|
+
uses: codecov/codecov-action@v5
|
|
43
|
+
with:
|
|
44
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
45
|
+
slug: lucalista/shinestacker
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Read the Docs configuration file
|
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
3
|
+
|
|
4
|
+
# Required
|
|
5
|
+
version: 2
|
|
6
|
+
|
|
7
|
+
# Set the OS, Python version, and other tools you might need
|
|
8
|
+
build:
|
|
9
|
+
os: ubuntu-24.04
|
|
10
|
+
tools:
|
|
11
|
+
python: "3.12"
|
|
12
|
+
|
|
13
|
+
# Build documentation in the "docs/" directory with Sphinx
|
|
14
|
+
sphinx:
|
|
15
|
+
configuration: docs/conf.py
|
|
16
|
+
|
|
17
|
+
# Optionally, but recommended,
|
|
18
|
+
# declare the Python requirements required to build your documentation
|
|
19
|
+
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
|
|
20
|
+
python:
|
|
21
|
+
install:
|
|
22
|
+
- requirements: docs/requirements.txt
|
|
@@ -4,6 +4,26 @@ This page reports the main releases only and the main changes therein.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [v0.2.2] - 2025-07-28
|
|
8
|
+
**More stability and improved tests**
|
|
9
|
+
|
|
10
|
+
### Changes
|
|
11
|
+
|
|
12
|
+
* improved test suite and enhanced test coverage
|
|
13
|
+
* updated documentation
|
|
14
|
+
* some stability improvements
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## [v0.2.1] - 2025-07-27
|
|
19
|
+
**Icon location fix**
|
|
20
|
+
|
|
21
|
+
### Changes
|
|
22
|
+
|
|
23
|
+
* icon location fixed, compatibly with PyPI and bundle release build
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
7
27
|
## [v0.2.0] - 2025-07-27
|
|
8
28
|
**Stability improvements and new package name**
|
|
9
29
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shinestacker
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: ShineStacker
|
|
5
5
|
Author-email: Luca Lista <luka.lista@gmail.com>
|
|
6
6
|
License-Expression: LGPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/lucalista/shinestacker
|
|
8
|
+
Project-URL: Documentation, https://shinestacker.readthedocs.io/
|
|
7
9
|
Classifier: Programming Language :: Python :: 3
|
|
8
10
|
Classifier: Operating System :: OS Independent
|
|
9
11
|
Requires-Python: >=3.12
|
|
@@ -32,17 +34,18 @@ Dynamic: license-file
|
|
|
32
34
|
[](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml)
|
|
33
35
|
[](https://pypi.org/project/shinestacker/)
|
|
34
36
|
[](https://pypi.org/project/shinestacker/)
|
|
37
|
+
[](https://codecov.io/github/lucalista/shinestacker)
|
|
35
38
|
|
|
36
|
-
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400">
|
|
39
|
+
<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">
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
# Documentation
|
|
39
42
|
|
|
40
43
|
📖 [Main documentation](https://github.com/lucalista/shinestacker/blob/main/docs/main.md) • 📝 [Changelog](https://github.com/lucalista/shinestacker/blob/main/CHANGELOG.md)
|
|
41
44
|
|
|
42
45
|
|
|
43
|
-
# Credits
|
|
46
|
+
# Credits
|
|
44
47
|
|
|
45
|
-
The main pyramid stack algorithm was inspired by the [Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation by Sami Jawhar
|
|
48
|
+
The main pyramid stack algorithm was initially inspired by the [Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation by Sami Jawhar that was used under permission of the author for initial versions of this package. The implementation in the latest releases was rewritten from the original code.
|
|
46
49
|
|
|
47
50
|
# Resources
|
|
48
51
|
|
|
@@ -3,17 +3,18 @@
|
|
|
3
3
|
[](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml)
|
|
4
4
|
[](https://pypi.org/project/shinestacker/)
|
|
5
5
|
[](https://pypi.org/project/shinestacker/)
|
|
6
|
+
[](https://codecov.io/github/lucalista/shinestacker)
|
|
6
7
|
|
|
7
|
-
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400">
|
|
8
|
+
<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">
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
# Documentation
|
|
10
11
|
|
|
11
12
|
📖 [Main documentation](https://github.com/lucalista/shinestacker/blob/main/docs/main.md) • 📝 [Changelog](https://github.com/lucalista/shinestacker/blob/main/CHANGELOG.md)
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
# Credits
|
|
15
|
+
# Credits
|
|
15
16
|
|
|
16
|
-
The main pyramid stack algorithm was inspired by the [Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation by Sami Jawhar
|
|
17
|
+
The main pyramid stack algorithm was initially inspired by the [Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation by Sami Jawhar that was used under permission of the author for initial versions of this package. The implementation in the latest releases was rewritten from the original code.
|
|
17
18
|
|
|
18
19
|
# Resources
|
|
19
20
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Alignment and registration
|
|
1
|
+
# Alignment and registration
|
|
2
|
+
|
|
3
|
+
Automatically align, scale, tanslate and rotate or apply full perspective correction.
|
|
2
4
|
|
|
3
5
|
```python
|
|
4
6
|
job.add_action(Actions("align", [AlignFrames(*options)])
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
sys.path.insert(0, os.path.abspath('../src'))
|
|
4
|
+
|
|
5
|
+
project = 'Shine Stacker'
|
|
6
|
+
author = 'Luca Lista'
|
|
7
|
+
html_title = "Shine Stacker Documentation"
|
|
8
|
+
|
|
9
|
+
extensions = [
|
|
10
|
+
'myst_parser',
|
|
11
|
+
'sphinx.ext.mathjax',
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
myst_enable_extensions = [
|
|
15
|
+
"dollarmath",
|
|
16
|
+
"amsmath",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
source_suffix = {
|
|
20
|
+
'.rst': 'restructuredtext',
|
|
21
|
+
'.md': 'markdown',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
master_doc = 'index'
|
|
25
|
+
|
|
26
|
+
html_theme = 'furo'
|
|
27
|
+
|
|
28
|
+
extensions = [
|
|
29
|
+
'myst_parser',
|
|
30
|
+
'sphinx.ext.autodoc',
|
|
31
|
+
'sphinx.ext.napoleon',
|
|
32
|
+
'sphinx.ext.autosummary',
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '**/.ipynb_checkpoints']
|
|
36
|
+
|
|
37
|
+
autosummary_generate = True
|
|
38
|
+
autodoc_default_options = {
|
|
39
|
+
'members': True,
|
|
40
|
+
'undoc-members': True,
|
|
41
|
+
'show-inheritance': True,
|
|
42
|
+
}
|
|
@@ -20,7 +20,7 @@ noisy pixel masking.
|
|
|
20
20
|
|
|
21
21
|
* If the app is dowloaded from the [releases page](https://github.com/lucalista/focusstack/releases), after the ```zip``` archive is uncompressed, just double-click the app icon.
|
|
22
22
|
|
|
23
|
-
<img src='
|
|
23
|
+
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/gui-finder.png' width="300" referrerpolicy="no-referrer">
|
|
24
24
|
|
|
25
25
|
**Platform Tip**: Windows apps are inside `/focusstack/`, macOS/Linux apps are directly in the uncompressed folder.
|
|
26
26
|
|
|
@@ -35,7 +35,7 @@ Switching from *Project* to *Retouch* can be done from the *FocusStack* main men
|
|
|
35
35
|
|
|
36
36
|
When the app starts, it proposes to create a new project.
|
|
37
37
|
|
|
38
|
-
<img src='
|
|
38
|
+
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/gui-project-new.png' width="600" referrerpolicy="no-referrer">
|
|
39
39
|
|
|
40
40
|
### Creating Projects
|
|
41
41
|
1. Select source folder (JPEG/TIFF 8/16-bit)
|
|
@@ -44,7 +44,7 @@ When the app starts, it proposes to create a new project.
|
|
|
44
44
|
- Real-time logs & progress bar
|
|
45
45
|
- Thumbnail previews for each stage
|
|
46
46
|
|
|
47
|
-
<img src='
|
|
47
|
+
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flow-diagram.png' width="900" alt="FocusStack workflow: Source images → Alignment → Balancing → Stacking" referrerpolicy="no-referrer">
|
|
48
48
|
|
|
49
49
|
> **Large Set Tip**: For 100+ images:
|
|
50
50
|
> - Split into 10-15 image "bunches"
|
|
@@ -63,7 +63,7 @@ Some actions can be combined in order to produce a single intermediate output (a
|
|
|
63
63
|
|
|
64
64
|
It is possible to run a single job, or all jobs within a project.
|
|
65
65
|
|
|
66
|
-
<img src='
|
|
66
|
+
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/gui-project-run.png' width="600" referrerpolicy="no-referrer">
|
|
67
67
|
|
|
68
68
|
### Project Run Tabs
|
|
69
69
|
|
|
@@ -75,7 +75,7 @@ When the job finishes, a *Retouch* button is enabled, which opens the output ima
|
|
|
75
75
|
|
|
76
76
|
## Retouch area
|
|
77
77
|
|
|
78
|
-
<img src='
|
|
78
|
+
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/gui-retouch.png' width="600" referrerpolicy="no-referrer">
|
|
79
79
|
|
|
80
80
|
### Brush Properties
|
|
81
81
|
Adjust in the top toolbar:
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Shine Stacker
|
|
2
|
+
|
|
3
|
+
## Focus Stacking Processing Framework and GUI
|
|
4
|
+
|
|
5
|
+
[](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml)
|
|
6
|
+
[](https://pypi.org/project/shinestacker/)
|
|
7
|
+
[](https://pypi.org/project/shinestacker/)
|
|
8
|
+
[](https://codecov.io/github/lucalista/shinestacker)
|
|
9
|
+
|
|
10
|
+
```{toctree}
|
|
11
|
+
:maxdepth: 2
|
|
12
|
+
:caption: Content
|
|
13
|
+
|
|
14
|
+
main.md
|
|
15
|
+
gui.md
|
|
16
|
+
job.md
|
|
17
|
+
alignment.md
|
|
18
|
+
balancing.md
|
|
19
|
+
focus_stacking.md
|
|
20
|
+
multilayer.md
|
|
21
|
+
noise.md
|
|
22
|
+
vignetting.md
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Job creation
|
|
1
|
+
# Job creation and action scheduling
|
|
2
2
|
|
|
3
3
|
Create a job, then schedule the desired actions in a job, then run the job.
|
|
4
4
|
|
|
@@ -13,7 +13,7 @@ Arguments are:
|
|
|
13
13
|
* ```callbacks``` (optional, default: ```None```): dictionary of callback functions for internal use. If equal to ```'tqdm'```, a progress bar is shown in either text mode or jupyter notebook.
|
|
14
14
|
* ```enabled``` (optional, default: ```True```): allows to switch on and off all actions within a job.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
## Schedule multiple actions based on a reference image: align and/or balance images
|
|
17
17
|
|
|
18
18
|
The class ```CombinedActions``` runs multiple actions on each of the frames appearing in a path.
|
|
19
19
|
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
[](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml)
|
|
4
4
|
[](https://pypi.org/project/shinestacker/)
|
|
5
5
|
[](https://pypi.org/project/shinestacker/)
|
|
6
|
+
[](https://codecov.io/github/lucalista/shinestacker)
|
|
6
7
|
|
|
7
|
-
<img src='
|
|
8
|
+
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400">
|
|
8
9
|
|
|
9
10
|
> **Professional focus stacking** for microscopy, macro photography, and computational imaging
|
|
10
11
|
|
|
@@ -78,14 +79,14 @@ job.run()
|
|
|
78
79
|
|
|
79
80
|
## Documentation Highlights
|
|
80
81
|
### Core Processing
|
|
81
|
-
- [Graphical User Interface](
|
|
82
|
-
- [Image alignment](
|
|
83
|
-
- [Luminosity and color balancing](
|
|
84
|
-
- [Stacking algorithms](
|
|
82
|
+
- [Graphical User Interface](gui.md)
|
|
83
|
+
- [Image alignment](alignment.md)
|
|
84
|
+
- [Luminosity and color balancing](balancing.md)
|
|
85
|
+
- [Stacking algorithms](focus_stacking.md)
|
|
85
86
|
### Advanced Modules
|
|
86
|
-
- [Noisy pixel masking](
|
|
87
|
-
- [Vignetting correction](
|
|
88
|
-
- [Multilayer image](
|
|
87
|
+
- [Noisy pixel masking](noise.md)
|
|
88
|
+
- [Vignetting correction](vignetting.md)
|
|
89
|
+
- [Multilayer image](multilayer.md)
|
|
89
90
|
|
|
90
91
|
## Requirements
|
|
91
92
|
|
|
@@ -98,12 +99,12 @@ job.run()
|
|
|
98
99
|
```bash
|
|
99
100
|
pip install imagecodecs matplotlib numpy opencv-python pillow psdtags scipy setuptools-scm tifffile tqdm
|
|
100
101
|
```
|
|
101
|
-
|
|
102
|
+
## GUI support
|
|
102
103
|
```bash
|
|
103
104
|
pip install argparse PySide6 jsonpickle webbrowser
|
|
104
105
|
```
|
|
105
106
|
|
|
106
|
-
|
|
107
|
+
## Jupyter support
|
|
107
108
|
```bash
|
|
108
109
|
pip install ipywidgets
|
|
109
110
|
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# flake8: noqa F401 F403
|
|
2
|
+
from ._version import __version__
|
|
3
|
+
from . import config
|
|
4
|
+
from . import core
|
|
5
|
+
from . import algorithms
|
|
6
|
+
from .config import __all__
|
|
7
|
+
from .core import __all__
|
|
8
|
+
from .algorithms import __all__
|
|
9
|
+
from .config import *
|
|
10
|
+
from .core import *
|
|
11
|
+
from .algorithms import *
|
|
12
|
+
|
|
13
|
+
__all__ = ['__version__']
|
|
14
|
+
#__all__ += config.__all__
|
|
15
|
+
#__all__ += core.__all__
|
|
16
|
+
#__all__ += algorithms.__all__
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.2.2'
|
|
@@ -12,3 +12,8 @@ from .vignetting import Vignetting
|
|
|
12
12
|
import logging
|
|
13
13
|
logger = logging.getLogger(__name__)
|
|
14
14
|
logger.addHandler(logging.NullHandler())
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
'StackJob', 'CombinedActions', 'AlignFrames', 'BalanceFrames', 'FocusStackBunch', 'FocusStack',
|
|
18
|
+
'DepthMapStack', 'PyramidStack', 'MultiLayer', 'NoiseDetection', 'MaskNoise', 'Vignetting'
|
|
19
|
+
]
|
|
@@ -62,7 +62,6 @@ def get_good_matches(des_0, des_1, matching_config=None):
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
def validate_align_config(detector, descriptor, match_method):
|
|
65
|
-
print(detector, descriptor, match_method)
|
|
66
65
|
if descriptor == constants.DESCRIPTOR_SIFT and match_method == constants.MATCHING_NORM_HAMMING:
|
|
67
66
|
raise ValueError("Descriptor SIFT requires matching method KNN")
|
|
68
67
|
if detector == constants.DETECTOR_ORB and descriptor == constants.DESCRIPTOR_AKAZE and \
|
|
@@ -12,7 +12,6 @@ from shinestacker.config.config import config
|
|
|
12
12
|
config.init(DISABLE_TQDM=True, COMBINED_APP=True, DONT_USE_NATIVE_MENU=True)
|
|
13
13
|
from shinestacker.config.constants import constants
|
|
14
14
|
from shinestacker.core.logging import setup_logging
|
|
15
|
-
from shinestacker.core.core_utils import get_app_base_path
|
|
16
15
|
from shinestacker.gui.main_window import MainWindow
|
|
17
16
|
from shinestacker.retouch.image_editor_ui import ImageEditorUI
|
|
18
17
|
from shinestacker.app.gui_utils import disable_macos_special_menu_items
|
|
@@ -12,7 +12,6 @@ from shinestacker.config.config import config
|
|
|
12
12
|
config.init(DISABLE_TQDM=True, DONT_USE_NATIVE_MENU=True)
|
|
13
13
|
from shinestacker.config.constants import constants
|
|
14
14
|
from shinestacker.core.logging import setup_logging
|
|
15
|
-
from shinestacker.core.core_utils import get_app_base_path
|
|
16
15
|
from shinestacker.gui.main_window import MainWindow
|
|
17
16
|
from shinestacker.app.gui_utils import disable_macos_special_menu_items
|
|
18
17
|
from shinestacker.app.help_menu import add_help_action
|
|
@@ -6,7 +6,6 @@ from PySide6.QtGui import QIcon, QAction
|
|
|
6
6
|
from PySide6.QtCore import Qt, QEvent
|
|
7
7
|
from shinestacker.config.config import config
|
|
8
8
|
config.init(DISABLE_TQDM=True, DONT_USE_NATIVE_MENU=True)
|
|
9
|
-
from shinestacker.core.core_utils import get_app_base_path
|
|
10
9
|
from shinestacker.config.config import config
|
|
11
10
|
from shinestacker.config.constants import constants
|
|
12
11
|
from shinestacker.retouch.image_editor_ui import ImageEditorUI
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# flake8: noqa F401
|
|
2
|
+
from .logging import setup_logging
|
|
3
|
+
from .exceptions import (FocusStackError, InvalidOptionError, ImageLoadError, ImageSaveError, AlignmentError,
|
|
4
|
+
BitDepthError, ShapeError, RunStopException)
|
|
5
|
+
from .framework import Job
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
'setup_logging',
|
|
9
|
+
'FocusStackError', 'InvalidOptionError', 'ImageLoadError', 'ImageSaveError',
|
|
10
|
+
'AlignmentError','BitDepthError', 'ShapeError', 'RunStopException',
|
|
11
|
+
'Job']
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from dataclasses import dataclass
|
|
3
3
|
from PySide6.QtWidgets import QMainWindow, QListWidget, QMessageBox, QDialog, QListWidgetItem, QLabel
|
|
4
|
-
from PySide6.QtGui import QIcon
|
|
5
4
|
from PySide6.QtCore import Qt
|
|
6
5
|
from .. config.constants import constants
|
|
7
6
|
from .colors import ColorPalette
|
|
@@ -3,7 +3,6 @@ from PIL.TiffImagePlugin import IFDRational
|
|
|
3
3
|
from PySide6.QtWidgets import QFormLayout, QHBoxLayout, QPushButton, QDialog, QLabel
|
|
4
4
|
from PySide6.QtGui import QIcon
|
|
5
5
|
from PySide6.QtCore import Qt
|
|
6
|
-
from .. core.core_utils import get_app_base_path
|
|
7
6
|
from .. algorithms.exif import exif_dict
|
|
8
7
|
|
|
9
8
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shinestacker
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: ShineStacker
|
|
5
5
|
Author-email: Luca Lista <luka.lista@gmail.com>
|
|
6
6
|
License-Expression: LGPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/lucalista/shinestacker
|
|
8
|
+
Project-URL: Documentation, https://shinestacker.readthedocs.io/
|
|
7
9
|
Classifier: Programming Language :: Python :: 3
|
|
8
10
|
Classifier: Operating System :: OS Independent
|
|
9
11
|
Requires-Python: >=3.12
|
|
@@ -32,17 +34,18 @@ Dynamic: license-file
|
|
|
32
34
|
[](https://github.com/lucalista/shinestacker/actions/workflows/ci-multiplatform.yml)
|
|
33
35
|
[](https://pypi.org/project/shinestacker/)
|
|
34
36
|
[](https://pypi.org/project/shinestacker/)
|
|
37
|
+
[](https://codecov.io/github/lucalista/shinestacker)
|
|
35
38
|
|
|
36
|
-
<img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies.gif' width="400"> <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/img/flies_stack.jpg' width="400">
|
|
39
|
+
<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">
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
# Documentation
|
|
39
42
|
|
|
40
43
|
📖 [Main documentation](https://github.com/lucalista/shinestacker/blob/main/docs/main.md) • 📝 [Changelog](https://github.com/lucalista/shinestacker/blob/main/CHANGELOG.md)
|
|
41
44
|
|
|
42
45
|
|
|
43
|
-
# Credits
|
|
46
|
+
# Credits
|
|
44
47
|
|
|
45
|
-
The main pyramid stack algorithm was inspired by the [Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation by Sami Jawhar
|
|
48
|
+
The main pyramid stack algorithm was initially inspired by the [Laplacian pyramids method](https://github.com/sjawhar/focus-stacking) implementation by Sami Jawhar that was used under permission of the author for initial versions of this package. The implementation in the latest releases was rewritten from the original code.
|
|
46
49
|
|
|
47
50
|
# Resources
|
|
48
51
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
.coverage
|
|
2
|
+
.coveragerc
|
|
1
3
|
.flake8
|
|
2
4
|
.gitignore
|
|
5
|
+
.readthedocs.yaml
|
|
3
6
|
CHANGELOG.md
|
|
4
7
|
LICENSE
|
|
5
8
|
README.md
|
|
@@ -8,13 +11,17 @@ pyproject.toml
|
|
|
8
11
|
.github/workflows/pypi-publish.yml
|
|
9
12
|
.github/workflows/release.yml
|
|
10
13
|
docs/alignment.md
|
|
14
|
+
docs/api.md
|
|
11
15
|
docs/balancing.md
|
|
16
|
+
docs/conf.py
|
|
12
17
|
docs/focus_stacking.md
|
|
13
18
|
docs/gui.md
|
|
19
|
+
docs/index.md
|
|
14
20
|
docs/job.md
|
|
15
21
|
docs/main.md
|
|
16
22
|
docs/multilayer.md
|
|
17
23
|
docs/noise.md
|
|
24
|
+
docs/requirements.txt
|
|
18
25
|
docs/vignetting.md
|
|
19
26
|
examples/balance-only.fsp
|
|
20
27
|
examples/complete-project.fsp
|
|
@@ -52,7 +59,6 @@ img/gui-finder.png
|
|
|
52
59
|
img/gui-project-new.png
|
|
53
60
|
img/gui-project-run.png
|
|
54
61
|
img/gui-retouch.png
|
|
55
|
-
sandbox/test_alignment_multiple.py
|
|
56
62
|
scripts/build_release.py
|
|
57
63
|
scripts/validate-tomli.py
|
|
58
64
|
src/shinestacker/__init__.py
|
|
@@ -138,8 +144,11 @@ tests/test-stack.ipynb
|
|
|
138
144
|
tests/test-vignetting.ipynb
|
|
139
145
|
tests/test_0000_logging.py
|
|
140
146
|
tests/test_0001_colors.py
|
|
147
|
+
tests/test_0002_config.py
|
|
141
148
|
tests/test_0005_make_test_img.py
|
|
149
|
+
tests/test_0006_exceptions.py
|
|
142
150
|
tests/test_0010_job.py
|
|
151
|
+
tests/test_0011_core_utils.py
|
|
143
152
|
tests/test_0020_noise_detection.py
|
|
144
153
|
tests/test_0030_align.py
|
|
145
154
|
tests/test_0031_align_precision.py
|
|
@@ -147,9 +156,11 @@ tests/test_0032_align_methods.py
|
|
|
147
156
|
tests/test_0040_balance.py
|
|
148
157
|
tests/test_0050_align_balance.py
|
|
149
158
|
tests/test_0060_stack.py
|
|
159
|
+
tests/test_0061_depth_map.py
|
|
150
160
|
tests/test_0070_multilayer.py
|
|
151
161
|
tests/test_0080_exif.py
|
|
152
162
|
tests/test_0090_vignetting.py
|
|
163
|
+
tests/test_0091_vignetting_algo.py
|
|
153
164
|
tests/test_1000_brush_mask.py
|
|
154
165
|
tests/test_1010_gui.py
|
|
155
166
|
tests/test_1020_gui_images.py
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from shinestacker.config.config import _Config, config
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TestConfig:
|
|
6
|
+
def setup_method(self, method):
|
|
7
|
+
_Config._instance = None
|
|
8
|
+
_Config._initialized = False
|
|
9
|
+
|
|
10
|
+
def test_singleton_pattern(self):
|
|
11
|
+
config1 = _Config()
|
|
12
|
+
config2 = _Config()
|
|
13
|
+
assert config1 is config2
|
|
14
|
+
|
|
15
|
+
def test_default_values(self):
|
|
16
|
+
test_config = _Config()
|
|
17
|
+
assert test_config.DISABLE_TQDM is False
|
|
18
|
+
assert test_config.COMBINED_APP is False
|
|
19
|
+
assert test_config.DONT_USE_NATIVE_MENU is True
|
|
20
|
+
|
|
21
|
+
def test_init_method_valid_keys(self):
|
|
22
|
+
test_config = _Config()
|
|
23
|
+
test_config.init(
|
|
24
|
+
DISABLE_TQDM=True,
|
|
25
|
+
COMBINED_APP=True,
|
|
26
|
+
DONT_USE_NATIVE_MENU=False
|
|
27
|
+
)
|
|
28
|
+
assert test_config.DISABLE_TQDM is True
|
|
29
|
+
assert test_config.COMBINED_APP is True
|
|
30
|
+
assert test_config.DONT_USE_NATIVE_MENU is False
|
|
31
|
+
|
|
32
|
+
def test_init_method_invalid_key(self):
|
|
33
|
+
test_config = _Config()
|
|
34
|
+
with pytest.raises(AttributeError) as excinfo:
|
|
35
|
+
test_config.init(INVALID_KEY=True)
|
|
36
|
+
assert "Invalid config key" in str(excinfo.value)
|
|
37
|
+
|
|
38
|
+
def test_init_method_already_initialized(self):
|
|
39
|
+
test_config = _Config()
|
|
40
|
+
test_config.init(DISABLE_TQDM=True)
|
|
41
|
+
with pytest.raises(RuntimeError) as excinfo:
|
|
42
|
+
test_config.init(DISABLE_TQDM=False)
|
|
43
|
+
assert "Config already initialized" in str(excinfo.value)
|
|
44
|
+
|
|
45
|
+
def test_property_access(self):
|
|
46
|
+
test_config = _Config()
|
|
47
|
+
assert test_config.DISABLE_TQDM == test_config._DISABLE_TQDM
|
|
48
|
+
assert test_config.COMBINED_APP == test_config._COMBINED_APP
|
|
49
|
+
assert test_config.DONT_USE_NATIVE_MENU == test_config._DONT_USE_NATIVE_MENU
|
|
50
|
+
|
|
51
|
+
def test_immutable_after_init(self):
|
|
52
|
+
test_config = _Config()
|
|
53
|
+
test_config.init(DISABLE_TQDM=True)
|
|
54
|
+
with pytest.raises(AttributeError):
|
|
55
|
+
test_config._DISABLE_TQDM = False
|
|
56
|
+
test_config.some_new_attr = "value"
|
|
57
|
+
|
|
58
|
+
def test_jupyter_notebook_detection(self):
|
|
59
|
+
test_config = _Config()
|
|
60
|
+
assert isinstance(test_config.JUPYTER_NOTEBOOK, bool)
|