geomosaic 0.1.0__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.
@@ -0,0 +1,53 @@
1
+ name: Deploy notebook to GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
13
+ concurrency:
14
+ group: "pages"
15
+ cancel-in-progress: false
16
+
17
+ jobs:
18
+ test:
19
+ uses: ./.github/workflows/tests.yml # never deploy a demo from a red build
20
+
21
+ build:
22
+ needs: test
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+
27
+ - name: Install uv
28
+ uses: astral-sh/setup-uv@v5
29
+
30
+ - name: Install dependencies
31
+ run: uv sync --all-groups
32
+
33
+ - name: Check WASM compatibility
34
+ run: uv run marimo check notebooks/png2svg.py --select MW
35
+
36
+ - name: Export notebook to WASM-powered HTML
37
+ run: uv run marimo export html-wasm notebooks/png2svg.py -o site --mode run
38
+
39
+ - name: Upload Pages artifact
40
+ uses: actions/upload-pages-artifact@v3
41
+ with:
42
+ path: site
43
+
44
+ deploy:
45
+ needs: build
46
+ runs-on: ubuntu-latest
47
+ environment:
48
+ name: github-pages
49
+ url: ${{ steps.deployment.outputs.page_url }}
50
+ steps:
51
+ - name: Deploy to GitHub Pages
52
+ id: deployment
53
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,34 @@
1
+ name: Publish package
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ test:
14
+ uses: ./.github/workflows/tests.yml
15
+
16
+ build-and-publish:
17
+ needs: test
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v5
24
+
25
+ - name: Build package
26
+ run: uv build
27
+
28
+ - name: Create GitHub Release
29
+ uses: softprops/action-gh-release@v2
30
+ with:
31
+ generate_release_notes: true
32
+
33
+ - name: Publish to PyPI
34
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,37 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ workflow_call:
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ python-version: ["3.12", "3.13"]
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: uv sync --all-groups
26
+
27
+ - name: Check formatting
28
+ run: uv run ruff format --check .
29
+
30
+ - name: Lint
31
+ run: uv run ruff check .
32
+
33
+ - name: Type check
34
+ run: uv run mypy src
35
+
36
+ - name: Run tests with coverage
37
+ run: uv run pytest --cov=src --cov-report=term-missing --cov-report=xml
@@ -0,0 +1,20 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+ .pytest_cache/
9
+
10
+ # Virtual environments
11
+ .venv
12
+ .python-version
13
+
14
+ .ruff_cache
15
+
16
+ .coverage
17
+ coverage.xml
18
+ htmlcov/
19
+
20
+ notebooks/__marimo__/
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.5
2
+ Name: geomosaic
3
+ Version: 0.1.0
4
+ Summary: A Python CLI tool to convert images into hexagonal SVG mosaics
5
+ Author-email: GRANDJEAN Mathieu <mathieu.grandjean@etu.imt-nord-europe.fr>
6
+ License: MIT
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Topic :: Multimedia :: Graphics
11
+ Requires-Python: >=3.12
12
+ Requires-Dist: numpy>=2.5.3
13
+ Requires-Dist: pillow>=12.3.0
File without changes
Binary file
@@ -0,0 +1,6 @@
1
+ def main():
2
+ print("Hello from png-to-svg!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -0,0 +1,108 @@
1
+ import marimo
2
+
3
+ __generated_with = "0.25.1"
4
+ app = marimo.App()
5
+
6
+
7
+ @app.cell
8
+ def _():
9
+ import io
10
+ import marimo as mo
11
+ import matplotlib.pyplot as plt
12
+ import numpy as np
13
+
14
+ from hexagrid.hexagon import generate_hexagonal_grid, Hexagon
15
+ from hexagrid.svg import export_to_svg
16
+ from PIL import Image
17
+
18
+ return Image, export_to_svg, generate_hexagonal_grid, io, mo, np
19
+
20
+
21
+ @app.cell(hide_code=True)
22
+ def _(mo):
23
+ mo.md(r"""
24
+ # Hexagrid : Convert an image (.png, .jpg, etc.) into a SVG mosaic
25
+
26
+ Drag and drop an image and adjust parameters to generate the vectorized mosaic.
27
+ """)
28
+ return
29
+
30
+
31
+ @app.cell
32
+ def _(mo):
33
+ file_picker = mo.ui.file(
34
+ filetypes=[".png", ".jpg", ".jpeg", ".webp"],
35
+ label="Choose an image to convert"
36
+ )
37
+
38
+ size_input = mo.ui.number(
39
+ start=1.0, stop=100.0, step=1.0, value=15.0,
40
+ label="Size of the hexagons (flat-top)"
41
+ )
42
+
43
+ margin_input = mo.ui.number(
44
+ start=0, stop=10, step=1, value=2,
45
+ label="Grid margin"
46
+ )
47
+
48
+ mo.vstack([file_picker, size_input, margin_input])
49
+ return file_picker, margin_input, size_input
50
+
51
+
52
+ @app.cell
53
+ def _(
54
+ Image,
55
+ export_to_svg,
56
+ file_picker,
57
+ generate_hexagonal_grid,
58
+ io,
59
+ margin_input,
60
+ mo,
61
+ np,
62
+ size_input,
63
+ ):
64
+ if file_picker.value:
65
+ uploaded_file = file_picker.value[0]
66
+
67
+ img = Image.open(io.BytesIO(uploaded_file.contents)).convert("RGB")
68
+
69
+ hex_grid = generate_hexagonal_grid(
70
+ img.width, img.height,
71
+ size_input.value,
72
+ margin=int(margin_input.value)
73
+ )
74
+
75
+ for h in hex_grid:
76
+ h.compute_average_color_random(np.asarray(img))
77
+
78
+ output_filename = f"output_{uploaded_file.name.rsplit('.', 1)[0]}.svg"
79
+ export_to_svg(hex_grid, img.width, img.height, output_filename)
80
+
81
+ result = mo.hstack([
82
+ mo.vstack([
83
+ mo.md("**Original Image**"),
84
+ mo.image(src=uploaded_file.contents, width=500)
85
+ ]),
86
+ mo.vstack([
87
+ mo.md("**SVG Mosaic**"),
88
+ mo.image(src=f"output_{uploaded_file.name.rsplit('.', 1)[0]}.svg", width=500)
89
+ ]),
90
+ mo.vstack([
91
+ mo.md("**Result**"),
92
+ mo.md(f"""
93
+ * **Generated file:** `{output_filename}`
94
+ * **Hexagons size:** {size_input.value}
95
+ * **Hexagon number:** {len(hex_grid)}
96
+ """)
97
+ ])
98
+ ])
99
+
100
+ else:
101
+ result = mo.md("### Please select an image to start the conversion.")
102
+
103
+ result
104
+ return
105
+
106
+
107
+ if __name__ == "__main__":
108
+ app.run()