silukman-image-vectorizer 1.0.5__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.
Files changed (33) hide show
  1. silukman_image_vectorizer-1.0.5/LICENSE +30 -0
  2. silukman_image_vectorizer-1.0.5/PKG-INFO +119 -0
  3. silukman_image_vectorizer-1.0.5/README.md +92 -0
  4. silukman_image_vectorizer-1.0.5/app/__init__.py +1 -0
  5. silukman_image_vectorizer-1.0.5/app/cli.py +73 -0
  6. silukman_image_vectorizer-1.0.5/app/config/__init__.py +1 -0
  7. silukman_image_vectorizer-1.0.5/app/config/settings.py +40 -0
  8. silukman_image_vectorizer-1.0.5/app/core/__init__.py +1 -0
  9. silukman_image_vectorizer-1.0.5/app/core/constants.py +6 -0
  10. silukman_image_vectorizer-1.0.5/app/core/image_pipeline.py +51 -0
  11. silukman_image_vectorizer-1.0.5/app/core/paths.py +13 -0
  12. silukman_image_vectorizer-1.0.5/app/core/vectorization_engine.py +360 -0
  13. silukman_image_vectorizer-1.0.5/app/core/vectorizer_backend.py +373 -0
  14. silukman_image_vectorizer-1.0.5/app/main_window.py +1714 -0
  15. silukman_image_vectorizer-1.0.5/app/resources/__init__.py +1 -0
  16. silukman_image_vectorizer-1.0.5/app/resources/hero_image.png +0 -0
  17. silukman_image_vectorizer-1.0.5/app/resources/icon.icns +0 -0
  18. silukman_image_vectorizer-1.0.5/app/resources/icon.png +0 -0
  19. silukman_image_vectorizer-1.0.5/app/services/__init__.py +1 -0
  20. silukman_image_vectorizer-1.0.5/app/services/batch_processor.py +171 -0
  21. silukman_image_vectorizer-1.0.5/app/services/color_palette.py +110 -0
  22. silukman_image_vectorizer-1.0.5/app/services/image_loader.py +120 -0
  23. silukman_image_vectorizer-1.0.5/app/services/svg_exporter.py +191 -0
  24. silukman_image_vectorizer-1.0.5/app/ui/__init__.py +1 -0
  25. silukman_image_vectorizer-1.0.5/app/ui/theme.py +316 -0
  26. silukman_image_vectorizer-1.0.5/pyproject.toml +48 -0
  27. silukman_image_vectorizer-1.0.5/setup.cfg +4 -0
  28. silukman_image_vectorizer-1.0.5/silukman_image_vectorizer.egg-info/PKG-INFO +119 -0
  29. silukman_image_vectorizer-1.0.5/silukman_image_vectorizer.egg-info/SOURCES.txt +31 -0
  30. silukman_image_vectorizer-1.0.5/silukman_image_vectorizer.egg-info/dependency_links.txt +1 -0
  31. silukman_image_vectorizer-1.0.5/silukman_image_vectorizer.egg-info/entry_points.txt +2 -0
  32. silukman_image_vectorizer-1.0.5/silukman_image_vectorizer.egg-info/requires.txt +5 -0
  33. silukman_image_vectorizer-1.0.5/silukman_image_vectorizer.egg-info/top_level.txt +1 -0
@@ -0,0 +1,30 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Image Vectorizer Developers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+ Third-Party Software Attributions:
25
+ This application bundles and uses the following open-source libraries:
26
+ - PySide6 (LGPL v3) - https://www.qt.io/qt-for-python
27
+ - OpenCV Python (Apache License 2.0) - https://github.com/opencv/opencv-python
28
+ - Pillow (HPND License) - https://github.com/python-pillow/Pillow
29
+ - Numpy (BSD-3-Clause) - https://github.com/numpy/numpy
30
+ - VTracer (MIT License) - https://github.com/visioncortex/vtracer
@@ -0,0 +1,119 @@
1
+ Metadata-Version: 2.4
2
+ Name: silukman-image-vectorizer
3
+ Version: 1.0.5
4
+ Summary: A PySide6 desktop application for high-quality raster-to-vector (SVG) conversion.
5
+ Author: Lukman-ss
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/lukman-ss/silukman_image_vectorizer
8
+ Project-URL: Bug-Tracker, https://github.com/lukman-ss/silukman_image_vectorizer/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Environment :: X11 Applications :: Qt
16
+ Classifier: Intended Audience :: End Users/Desktop
17
+ Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
18
+ Requires-Python: >=3.9
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: PySide6>=6.0.0
22
+ Requires-Dist: pillow>=9.0.0
23
+ Requires-Dist: opencv-python>=4.5.0
24
+ Requires-Dist: numpy>=1.20.0
25
+ Requires-Dist: vtracer>=0.1.6
26
+ Dynamic: license-file
27
+
28
+ # Image Vectorizer
29
+
30
+ ![Image Vectorizer Hero](app/resources/hero_image.png)
31
+
32
+ Last updated: 2026-06-05
33
+
34
+ Image Vectorizer is a Python and PySide6 desktop application foundation for
35
+ working with raster images. The current application supports local image import,
36
+ original and processed previews, image metadata display, and an initial
37
+ grayscale and threshold processing pipeline. It can also detect, simplify, and
38
+ preview color-aware vector paths using configurable quality, background removal,
39
+ and comparison controls. The desktop UI supports accessible Light, Dark, and
40
+ System theme modes, single SVG export, and responsive batch SVG processing.
41
+
42
+ ## Install Dependencies
43
+
44
+ ```bash
45
+ python -m pip install -r requirements.txt
46
+ ```
47
+
48
+ ## Run
49
+
50
+ From the project root:
51
+
52
+ ```bash
53
+ python main.py
54
+ ```
55
+
56
+ Or use the development runner:
57
+
58
+ ```bash
59
+ python scripts/run_dev.py
60
+ ```
61
+
62
+ ## Build & Packaging
63
+
64
+ To bundle the application into a standalone desktop executable for distribution:
65
+
66
+ ### On Windows
67
+ ```cmd
68
+ .venv\Scripts\python scripts\build_app.py
69
+ ```
70
+
71
+ ### On macOS / Linux
72
+ ```bash
73
+ .venv/bin/python scripts/build_app.py
74
+ ```
75
+
76
+ The script will automatically handle:
77
+ 1. Cleaning previous build output folders.
78
+ 2. Generating a clean build using the configuration from `image_vectorizer.spec`.
79
+ 3. Creating the standalone package in the `dist/` directory.
80
+ 4. Auto-detecting the application icon in `app/resources` using the native
81
+ platform icon format when available.
82
+ 5. Running a post-build cleanup on temporary compilation artifacts.
83
+ 6. Using PyInstaller from `.venv` or the system PATH.
84
+
85
+ ## Documentation
86
+
87
+ Project documentation is available in `docs/`.
88
+
89
+ - `docs/architecture/` for system and pipeline architecture.
90
+ - `docs/developer/` for setup, verification, benchmark, and packaging guides.
91
+ - `docs/product/` for project overview, glossary, status, and roadmap.
92
+ - `docs/user/` for UI workflow, performance tips, and troubleshooting.
93
+
94
+ ## CI/CD & Release Automation
95
+
96
+ We use GitHub Actions to automate desktop application builds, version tagging, and release publishing.
97
+
98
+ ### 1. CI Build Workflow (`build.yml`)
99
+ - Triggered automatically on push or pull requests to the `main` branch, or via manual run (`workflow_dispatch`).
100
+ - Builds standalone application packages for Windows, macOS, and Linux in parallel.
101
+ - Uploads the build outputs as workflow artifacts (`Image-Vectorizer-Windows`, `Image-Vectorizer-macOS`, `Image-Vectorizer-Linux`).
102
+
103
+ ### 2. Manual Tag Workflow (`create_tag.yml`)
104
+ - Triggered manually from the Actions tab.
105
+ - Accepts a semantic version tag (e.g. `v1.0.0`) and pushes it to the repository after validating that the format matches `v*.*.*` and the tag does not already exist.
106
+
107
+ ### 3. Release Publication Workflow (`release.yml`)
108
+ - Automatically triggered when a new version tag (`v*.*.*`) is pushed.
109
+ - Re-builds the application packages for all target platforms, compiles them, and attaches the archived builds to a newly created GitHub Release using the version number as the release name.
110
+
111
+ ### 4. PyPI Publishing Workflow (`publish_pypi.yml`)
112
+ - Triggered automatically when a new version tag (`v*.*.*`) is pushed, or via manual run (`workflow_dispatch`).
113
+ - Compiles the source distribution and wheel packages, validates package metadata using `twine`, and publishes the package to PyPI under the name `silukman-image-vectorizer` using the repository secret `PYPI_API_TOKEN`.
114
+
115
+ ### Difference Between Manual and CI Build
116
+ - **Manual Build**: Runs locally via `scripts/build_app.py`. Uses local system libraries, virtual environment compilers, and target architecture. Best for fast local verification.
117
+ - **CI Build**: Runs inside clean, isolated containers on GitHub-hosted runners (Windows, macOS, Linux). Guarantees reproducible builds and doesn't pollute local environments.
118
+
119
+
@@ -0,0 +1,92 @@
1
+ # Image Vectorizer
2
+
3
+ ![Image Vectorizer Hero](app/resources/hero_image.png)
4
+
5
+ Last updated: 2026-06-05
6
+
7
+ Image Vectorizer is a Python and PySide6 desktop application foundation for
8
+ working with raster images. The current application supports local image import,
9
+ original and processed previews, image metadata display, and an initial
10
+ grayscale and threshold processing pipeline. It can also detect, simplify, and
11
+ preview color-aware vector paths using configurable quality, background removal,
12
+ and comparison controls. The desktop UI supports accessible Light, Dark, and
13
+ System theme modes, single SVG export, and responsive batch SVG processing.
14
+
15
+ ## Install Dependencies
16
+
17
+ ```bash
18
+ python -m pip install -r requirements.txt
19
+ ```
20
+
21
+ ## Run
22
+
23
+ From the project root:
24
+
25
+ ```bash
26
+ python main.py
27
+ ```
28
+
29
+ Or use the development runner:
30
+
31
+ ```bash
32
+ python scripts/run_dev.py
33
+ ```
34
+
35
+ ## Build & Packaging
36
+
37
+ To bundle the application into a standalone desktop executable for distribution:
38
+
39
+ ### On Windows
40
+ ```cmd
41
+ .venv\Scripts\python scripts\build_app.py
42
+ ```
43
+
44
+ ### On macOS / Linux
45
+ ```bash
46
+ .venv/bin/python scripts/build_app.py
47
+ ```
48
+
49
+ The script will automatically handle:
50
+ 1. Cleaning previous build output folders.
51
+ 2. Generating a clean build using the configuration from `image_vectorizer.spec`.
52
+ 3. Creating the standalone package in the `dist/` directory.
53
+ 4. Auto-detecting the application icon in `app/resources` using the native
54
+ platform icon format when available.
55
+ 5. Running a post-build cleanup on temporary compilation artifacts.
56
+ 6. Using PyInstaller from `.venv` or the system PATH.
57
+
58
+ ## Documentation
59
+
60
+ Project documentation is available in `docs/`.
61
+
62
+ - `docs/architecture/` for system and pipeline architecture.
63
+ - `docs/developer/` for setup, verification, benchmark, and packaging guides.
64
+ - `docs/product/` for project overview, glossary, status, and roadmap.
65
+ - `docs/user/` for UI workflow, performance tips, and troubleshooting.
66
+
67
+ ## CI/CD & Release Automation
68
+
69
+ We use GitHub Actions to automate desktop application builds, version tagging, and release publishing.
70
+
71
+ ### 1. CI Build Workflow (`build.yml`)
72
+ - Triggered automatically on push or pull requests to the `main` branch, or via manual run (`workflow_dispatch`).
73
+ - Builds standalone application packages for Windows, macOS, and Linux in parallel.
74
+ - Uploads the build outputs as workflow artifacts (`Image-Vectorizer-Windows`, `Image-Vectorizer-macOS`, `Image-Vectorizer-Linux`).
75
+
76
+ ### 2. Manual Tag Workflow (`create_tag.yml`)
77
+ - Triggered manually from the Actions tab.
78
+ - Accepts a semantic version tag (e.g. `v1.0.0`) and pushes it to the repository after validating that the format matches `v*.*.*` and the tag does not already exist.
79
+
80
+ ### 3. Release Publication Workflow (`release.yml`)
81
+ - Automatically triggered when a new version tag (`v*.*.*`) is pushed.
82
+ - Re-builds the application packages for all target platforms, compiles them, and attaches the archived builds to a newly created GitHub Release using the version number as the release name.
83
+
84
+ ### 4. PyPI Publishing Workflow (`publish_pypi.yml`)
85
+ - Triggered automatically when a new version tag (`v*.*.*`) is pushed, or via manual run (`workflow_dispatch`).
86
+ - Compiles the source distribution and wheel packages, validates package metadata using `twine`, and publishes the package to PyPI under the name `silukman-image-vectorizer` using the repository secret `PYPI_API_TOKEN`.
87
+
88
+ ### Difference Between Manual and CI Build
89
+ - **Manual Build**: Runs locally via `scripts/build_app.py`. Uses local system libraries, virtual environment compilers, and target architecture. Best for fast local verification.
90
+ - **CI Build**: Runs inside clean, isolated containers on GitHub-hosted runners (Windows, macOS, Linux). Guarantees reproducible builds and doesn't pollute local environments.
91
+
92
+
@@ -0,0 +1 @@
1
+ """Image Vectorizer application package."""
@@ -0,0 +1,73 @@
1
+ import sys
2
+ import traceback
3
+
4
+
5
+ def _show_startup_error(title: str, message: str) -> None:
6
+ try:
7
+ from PySide6.QtWidgets import QApplication, QMessageBox
8
+
9
+ app = QApplication.instance()
10
+ created = False
11
+ if app is None:
12
+ app = QApplication(sys.argv)
13
+ created = True
14
+ QMessageBox.critical(None, title, message)
15
+ if created:
16
+ app.processEvents()
17
+ except Exception:
18
+ pass
19
+
20
+
21
+ def _validate_runtime_environment() -> None:
22
+ from app.core.paths import RESOURCES_DIR
23
+
24
+ required_resources = [
25
+ RESOURCES_DIR,
26
+ RESOURCES_DIR / "icon.png",
27
+ RESOURCES_DIR / "hero_image.png",
28
+ ]
29
+ missing_resources = [
30
+ str(path)
31
+ for path in required_resources
32
+ if not path.exists()
33
+ ]
34
+ if missing_resources:
35
+ missing = "\n".join(missing_resources)
36
+ raise RuntimeError(f"Missing packaged resource(s):\n{missing}")
37
+
38
+
39
+ def main() -> int:
40
+ try:
41
+ from PySide6.QtWidgets import QApplication
42
+
43
+ from app.main_window import MainWindow
44
+
45
+ _validate_runtime_environment()
46
+
47
+ application = QApplication(sys.argv)
48
+ application.setApplicationName("Image Vectorizer")
49
+
50
+ window = MainWindow()
51
+ window.show()
52
+ return application.exec()
53
+ except ImportError as error:
54
+ msg = (
55
+ f"Failed to start Image Vectorizer: missing dependency ({error}).\n\n"
56
+ "Please ensure all dependencies are installed correctly."
57
+ )
58
+ print(msg, file=sys.stderr)
59
+ _show_startup_error("Dependency Error", msg)
60
+ return 1
61
+ except Exception as error:
62
+ print(f"Failed to start Image Vectorizer: {error}", file=sys.stderr)
63
+ traceback.print_exc()
64
+
65
+ _show_startup_error(
66
+ "Startup Error",
67
+ f"Image Vectorizer could not start:\n{error}",
68
+ )
69
+ return 1
70
+
71
+
72
+ if __name__ == "__main__":
73
+ sys.exit(main())
@@ -0,0 +1 @@
1
+ """Application configuration package."""
@@ -0,0 +1,40 @@
1
+ from dataclasses import dataclass, field
2
+
3
+ DEFAULT_WINDOW_WIDTH = 1200
4
+ DEFAULT_WINDOW_HEIGHT = 760
5
+
6
+ @dataclass
7
+ class VTracerSettings:
8
+ """VTracer-specific settings."""
9
+ colormode: str = "color" # color / binary
10
+ hierarchical: str = "stacked" # stacked / cutout
11
+ mode: str = "spline" # spline / polygon / none
12
+ filter_speckle: int = 4 # speckle size filter
13
+ color_precision: int = 6 # 1 to 8 (safer default max 6 to prevent 128 colors)
14
+ layer_difference: int = 16 # color difference threshold
15
+ corner_threshold: int = 60 # angle threshold for corners
16
+ length_threshold: float = 3.5 # curve length threshold
17
+ max_iterations: int = 16 # optimizer max iteration count
18
+ path_precision: int = 8 # SVG path output decimal precision
19
+
20
+ @dataclass
21
+ class VectorizationSettings:
22
+ """Settings that control the vectorization process."""
23
+ # Legacy OpenCV settings
24
+ min_area: float = 100.0 # Minimum contour area to keep (pixels)
25
+ approx_tolerance: float = 2.0 # Douglas-Peucker epsilon for approximation
26
+ smoothing_enabled: bool = False # Whether to apply Gaussian smoothing pre-detection
27
+ invert: bool = False # Invert binary image before detection
28
+ color_mode: str = "Unlimited colors"
29
+ color_count: int = 8
30
+ preserve_edges: bool = False
31
+ remove_background: bool = False
32
+ bg_tolerance: float = 20.0
33
+ threshold_val: int = 127 # Threshold value for legacy engine
34
+ palette_replacements: list[tuple[tuple[int, int, int], tuple[int, int, int]]] = field(default_factory=list)
35
+
36
+ # Active engine type: "VTracer" or "OpenCV Legacy"
37
+ engine_type: str = "VTracer"
38
+
39
+ # VTracer settings object
40
+ vtracer: VTracerSettings = field(default_factory=VTracerSettings)
@@ -0,0 +1 @@
1
+ """Core application utilities."""
@@ -0,0 +1,6 @@
1
+ APP_VERSION = "1.0.5"
2
+ APPLICATION_TITLE = f"Image Vectorizer v{APP_VERSION}"
3
+ SIDEBAR_TITLE = "Sidebar"
4
+ PREVIEW_AREA_TITLE = "Preview Area"
5
+ CONTROL_PANEL_TITLE = "Control Panel"
6
+ STATUS_READY = "Ready"
@@ -0,0 +1,51 @@
1
+ from __future__ import annotations
2
+
3
+ import cv2
4
+ import numpy as np
5
+ from PySide6.QtGui import QImage
6
+
7
+
8
+ def process_image_pipeline(file_path: str, threshold_val: int) -> tuple[QImage, np.ndarray]:
9
+ """Run the image processing pipeline.
10
+
11
+ Stages:
12
+ 1. Load image and convert to grayscale.
13
+ 2. Apply binary thresholding.
14
+ """
15
+ if not isinstance(threshold_val, int) or isinstance(threshold_val, bool):
16
+ raise ValueError("Threshold value must be an integer.")
17
+ if not 0 <= threshold_val <= 255:
18
+ raise ValueError("Threshold value must be between 0 and 255.")
19
+
20
+ img = cv2.imread(file_path, cv2.IMREAD_UNCHANGED)
21
+ if img is None:
22
+ raise ValueError("Failed to load image for processing pipeline.")
23
+
24
+ if img.ndim == 2:
25
+ gray = img
26
+ elif img.shape[2] == 4:
27
+ gray = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
28
+ elif img.shape[2] == 3:
29
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
30
+ else:
31
+ raise ValueError("Unsupported image channel layout.")
32
+
33
+ # Stage 2: Threshold processing
34
+ _, thresholded = cv2.threshold(gray, threshold_val, 255, cv2.THRESH_BINARY)
35
+
36
+ # Convert grayscale/binary numpy array to QImage
37
+ height, width = thresholded.shape
38
+ thresholded = np.ascontiguousarray(thresholded)
39
+ bytes_per_line = thresholded.strides[0]
40
+
41
+ # QImage.Format_Grayscale8 is appropriate for single-channel 8-bit image data
42
+ q_image = QImage(
43
+ thresholded.data,
44
+ width,
45
+ height,
46
+ bytes_per_line,
47
+ QImage.Format.Format_Grayscale8
48
+ )
49
+
50
+ # Create a copy to ensure memory ownership of the pixel data is transferred to QImage
51
+ return q_image.copy(), thresholded
@@ -0,0 +1,13 @@
1
+ import sys
2
+ from pathlib import Path
3
+
4
+
5
+ if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
6
+ PROJECT_ROOT = Path(sys._MEIPASS)
7
+ else:
8
+ PROJECT_ROOT = Path(__file__).resolve().parents[2]
9
+
10
+ APP_DIR = PROJECT_ROOT / "app"
11
+ RESOURCES_DIR = APP_DIR / "resources"
12
+ DOCS_DIR = PROJECT_ROOT / "docs"
13
+ SCRIPTS_DIR = PROJECT_ROOT / "scripts"