quantum-pixel 2.0.1__tar.gz → 2.0.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.
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/Cargo.lock +1 -1
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/Cargo.toml +1 -1
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/PKG-INFO +3 -1
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/README.md +2 -0
- {quantum_pixel-2.0.1/quantum_pixel → quantum_pixel-2.0.2}/README_PYPI.md +2 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2/quantum_pixel}/README_PYPI.md +2 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/generator.py +2 -6
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/main.py +1 -1
- quantum_pixel-2.0.2/quantum_pixel/static/favicon.svg +37 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/templates/decode.html +2 -1
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/templates/encode.html +2 -1
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/templates/index.html +4 -3
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/web.py +8 -14
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/.github/FUNDING.yml +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/.github/workflows/CI.yml +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/.github/workflows/render-md-mermaid.yml +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/.gitignore +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/.python-version +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/LICENSE +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/assets/encoded.png +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/assets/grok.png +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/assets/intro.png +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/assets/material.png +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/assets/mermaid.png +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/assets/preview.png +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/pyproject.toml +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/__init__.py +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/static/decode.js +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/static/encode.js +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/static/robots.txt +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/static/styles.css +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/steganography.py +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/templates/error.html +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/quantum_pixel/templates/result.html +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/render.yaml +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/requirements.txt +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/src/lib.rs +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/tests/test_generator.py +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/tests/test_steganography.py +0 -0
- {quantum_pixel-2.0.1 → quantum_pixel-2.0.2}/uv.lock +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
edition = "2024"
|
|
3
3
|
name = "quantum-pixel"
|
|
4
|
-
version = "2.0.
|
|
4
|
+
version = "2.0.2"
|
|
5
5
|
authors = ["Linos1391 <linos.coding@gmail.com>"]
|
|
6
6
|
homepage = "https://github.com/Linos1391/quantum-pixel.git"
|
|
7
7
|
description = "When both YES and NO are existed. Only human with emotions can comprehend."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quantum-pixel
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Classifier: Development Status :: 5 - Production/Stable
|
|
5
5
|
Classifier: Natural Language :: English
|
|
6
6
|
Classifier: Programming Language :: Rust
|
|
@@ -24,6 +24,8 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
|
24
24
|
|
|
25
25
|
<h1>Quantum Pixel</h1>
|
|
26
26
|
|
|
27
|
+
<img src="https://raw.githubusercontent.com/Linos1391/quantum-pixel/bde7747758dd6f9a5fbd3fb06ce9a39528d348c6/quantum_pixel/static/favicon.svg" width="60%">
|
|
28
|
+
|
|
27
29
|
**When everything is possibility.**
|
|
28
30
|
|
|
29
31
|
[![][latest-release-shield]][latest-release-url]
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
<h1>Quantum Pixel</h1>
|
|
4
4
|
|
|
5
|
+
<img src="https://raw.githubusercontent.com/Linos1391/quantum-pixel/bde7747758dd6f9a5fbd3fb06ce9a39528d348c6/quantum_pixel/static/favicon.svg" width="60%">
|
|
6
|
+
|
|
5
7
|
**When everything is possibility.**
|
|
6
8
|
|
|
7
9
|
[![][latest-release-shield]][latest-release-url]
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
<h1>Quantum Pixel</h1>
|
|
4
4
|
|
|
5
|
+
<img src="https://raw.githubusercontent.com/Linos1391/quantum-pixel/bde7747758dd6f9a5fbd3fb06ce9a39528d348c6/quantum_pixel/static/favicon.svg" width="60%">
|
|
6
|
+
|
|
5
7
|
**When everything is possibility.**
|
|
6
8
|
|
|
7
9
|
[![][latest-release-shield]][latest-release-url]
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
<h1>Quantum Pixel</h1>
|
|
4
4
|
|
|
5
|
+
<img src="https://raw.githubusercontent.com/Linos1391/quantum-pixel/bde7747758dd6f9a5fbd3fb06ce9a39528d348c6/quantum_pixel/static/favicon.svg" width="60%">
|
|
6
|
+
|
|
5
7
|
**When everything is possibility.**
|
|
6
8
|
|
|
7
9
|
[![][latest-release-shield]][latest-release-url]
|
|
@@ -24,13 +24,9 @@ class Generator:
|
|
|
24
24
|
self._allowance: int = -1
|
|
25
25
|
self._remain_allowance: int = -1
|
|
26
26
|
|
|
27
|
-
def receive_current_progress(self):
|
|
28
|
-
"""This print out the percentage of completion. Dont know if really need."""
|
|
29
|
-
return int(100*(1-self._remain_allowance/self._allowance))
|
|
30
|
-
|
|
31
27
|
def preview(self, intensity: float, output_path: str) -> gen[int]:
|
|
32
28
|
"""
|
|
33
|
-
Generate the preview layer.
|
|
29
|
+
Generate the preview layer AND STREAM PROGRESS OUT.
|
|
34
30
|
```
|
|
35
31
|
generator = Generator("Path/to/image.png")
|
|
36
32
|
for progress in generator.preview(0.5, "Path/to/output/image.png"):
|
|
@@ -70,7 +66,7 @@ class Generator:
|
|
|
70
66
|
self._remain_allowance -= value
|
|
71
67
|
yield int(100*(1-self._remain_allowance/self._allowance))
|
|
72
68
|
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
|
73
|
-
Image.fromarray(layer.astype(np.uint8), "RGB").save(output_path
|
|
69
|
+
Image.fromarray(layer.astype(np.uint8), "RGB").save(output_path)
|
|
74
70
|
|
|
75
71
|
if __name__ == "__main__":
|
|
76
72
|
generator = Generator("assets/material.png")
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
|
|
4
|
+
<svg
|
|
5
|
+
width="10.923425"
|
|
6
|
+
height="5.6823688"
|
|
7
|
+
viewBox="0 0 10.923425 5.6823688"
|
|
8
|
+
version="1.1"
|
|
9
|
+
id="svg1"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs
|
|
13
|
+
id="defs1" />
|
|
14
|
+
<g
|
|
15
|
+
id="layer1"
|
|
16
|
+
transform="translate(-1.4484824,-5.2396302)">
|
|
17
|
+
<path
|
|
18
|
+
d="M 11.745412,5.2403227 A 1.2037493,5.9814274 65.401706 0 0 6.4153604,6.8618214 1.2037493,5.9814274 65.401706 0 0 1.4709457,10.447752 1.2037493,5.9814274 65.401706 0 0 7.4050302,9.0581793 1.2037493,5.9814274 65.401706 0 0 12.349444,5.4722485 1.2037493,5.9814274 65.401706 0 0 11.745412,5.2403227 Z M 11.344035,5.5574863 A 0.88875543,5.4451774 65.406484 0 1 11.861496,5.694263 0.88875543,5.4451774 65.406484 0 1 7.275173,8.7707497 0.88875543,5.4451774 65.406484 0 1 1.9588944,10.225738 0.88875543,5.4451774 65.406484 0 1 6.5452176,7.149251 0.88875543,5.4451774 65.406484 0 1 11.344035,5.5574863 Z"
|
|
19
|
+
style="fill:#33087b;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
|
20
|
+
id="path7" />
|
|
21
|
+
<text
|
|
22
|
+
xml:space="preserve"
|
|
23
|
+
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.2622px;font-family:Z003;-inkscape-font-specification:'Z003, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;writing-mode:lr-tb;direction:ltr;fill:#f7ee56;fill-opacity:1;stroke:#777777;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1"
|
|
24
|
+
x="1.5044148"
|
|
25
|
+
y="10.227339"
|
|
26
|
+
id="text5"
|
|
27
|
+
transform="scale(1.0682873,0.93607778)"><tspan
|
|
28
|
+
x="1.5044148"
|
|
29
|
+
y="10.227339"
|
|
30
|
+
id="tspan6"
|
|
31
|
+
style="fill:#f7ee56;fill-opacity:1;stroke:#777777;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1">QP</tspan></text>
|
|
32
|
+
<path
|
|
33
|
+
d="M 12.357315,5.4920713 11.871334,5.729944 A 0.88875543,5.4451774 65.406484 0 1 7.275173,8.7707497 0.88875543,5.4451774 65.406484 0 1 2.362239,10.366479 L 1.7857513,10.647962 A 1.2037493,5.9814274 65.401706 0 0 7.4050302,9.0581793 1.2037493,5.9814274 65.401706 0 0 12.357315,5.4920713 Z"
|
|
34
|
+
style="fill:#33087b;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
|
|
35
|
+
id="path8" />
|
|
36
|
+
</g>
|
|
37
|
+
</svg>
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
-
<
|
|
6
|
+
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
|
7
|
+
<title>Decode Image</title>
|
|
7
8
|
<link rel="stylesheet" href="/static/styles.css">
|
|
8
9
|
</head>
|
|
9
10
|
<body>
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
-
<
|
|
6
|
+
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
|
7
|
+
<title>Encode Image</title>
|
|
7
8
|
<link rel="stylesheet" href="/static/styles.css">
|
|
8
9
|
</head>
|
|
9
10
|
<body>
|
|
@@ -3,19 +3,20 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
-
<
|
|
6
|
+
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
|
7
|
+
<title>Upload Image</title>
|
|
7
8
|
<link rel="stylesheet" href="/static/styles.css">
|
|
8
9
|
</head>
|
|
9
10
|
<body>
|
|
10
11
|
<main class="container">
|
|
11
|
-
<h1>Upload an Image</h1>
|
|
12
|
+
<h1>Upload an Image (Only accept PNG)</h1>
|
|
12
13
|
|
|
13
14
|
{% if error %}
|
|
14
15
|
<div class="error">{{ error }}</div>
|
|
15
16
|
{% endif %}
|
|
16
17
|
|
|
17
18
|
<form class="upload-form" method="post" enctype="multipart/form-data">
|
|
18
|
-
<input type="file" name="file" accept="image
|
|
19
|
+
<input type="file" name="file" accept="image/png" required>
|
|
19
20
|
<button type="submit" name="upload_type" value="encode">Encode</button>
|
|
20
21
|
<button type="submit" name="upload_type" value="decode">Decode</button>
|
|
21
22
|
</form>
|
|
@@ -101,10 +101,6 @@ async def upload(request: Request):
|
|
|
101
101
|
if file.size > 1_073_741_824:
|
|
102
102
|
return templates.TemplateResponse("index.html",
|
|
103
103
|
{"request": request, "error": "File should be <1GB."})
|
|
104
|
-
_, ext = os.path.splitext(file.filename)
|
|
105
|
-
if ext.lower() not in (".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"):
|
|
106
|
-
return templates.TemplateResponse("index.html",
|
|
107
|
-
{"request": request, "error": "Unsupported file type."})
|
|
108
104
|
|
|
109
105
|
while True: # Guarantee an individualized uid.
|
|
110
106
|
uid = uuid.uuid4().hex
|
|
@@ -115,7 +111,8 @@ async def upload(request: Request):
|
|
|
115
111
|
continue
|
|
116
112
|
|
|
117
113
|
upload_type = form.get("upload_type")
|
|
118
|
-
|
|
114
|
+
with open(_join_uid(uid, f"{upload_type}_input.png"), "wb") as buffer:
|
|
115
|
+
shutil.copyfileobj(file.file, buffer)
|
|
119
116
|
return RedirectResponse(f"/{upload_type}/{uid}", status_code=303)
|
|
120
117
|
|
|
121
118
|
@app.get("/encode/{uid}", response_class=HTMLResponse)
|
|
@@ -145,21 +142,18 @@ async def end_encode(request: Request, uid: str):
|
|
|
145
142
|
if input_path and form.get("intensity"):
|
|
146
143
|
try:
|
|
147
144
|
future_item = asyncio.get_event_loop().run_in_executor(executor,
|
|
148
|
-
|
|
149
|
-
|
|
145
|
+
Generator(input_path).preview, float(form.get("intensity")),
|
|
146
|
+
_join_uid(uid, "encode_preview.png"))
|
|
150
147
|
future_item.add_done_callback(lambda _: _remove_from_list(uid))
|
|
151
148
|
background_task.update({uid: future_item})
|
|
152
149
|
|
|
153
150
|
async def _progress_streaming():
|
|
154
151
|
for progress in await future_item:
|
|
155
152
|
yield f"{progress}\n"
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
})})
|
|
161
|
-
|
|
162
|
-
return StreamingResponse(_progress_streaming(), media_type="text/plain")
|
|
153
|
+
yield json.dumps({"result": templates.get_template("result.html")
|
|
154
|
+
.render({"path": f"{uid}/encode_preview.png",
|
|
155
|
+
"download": "encode-preview",})})
|
|
156
|
+
return StreamingResponse(_progress_streaming(), media_type="text/plain")
|
|
163
157
|
|
|
164
158
|
except asyncio.exceptions.CancelledError:
|
|
165
159
|
return_error = "User exited."
|
|
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
|
|
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
|
|
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
|