get something working
- ID
6240da0- date
2022-05-04 21:34:04+00:00- author
Alex Chan <alex@alexwlchan.net>- parent
7829916- message
get something working- changed files
Changed files
webapp/requirements.in (0) → webapp/requirements.in (26)
diff --git a/webapp/requirements.in b/webapp/requirements.in
new file mode 100644
index 0000000..b028da6
--- /dev/null
+++ b/webapp/requirements.in
@@ -0,0 +1,2 @@
+flask
+wcag_contrast_ratio
webapp/requirements.txt (0) → webapp/requirements.txt (443)
diff --git a/webapp/requirements.txt b/webapp/requirements.txt
new file mode 100644
index 0000000..ef4ceb1
--- /dev/null
+++ b/webapp/requirements.txt
@@ -0,0 +1,24 @@
+#
+# This file is autogenerated by pip-compile with python 3.9
+# To update, run:
+#
+# pip-compile
+#
+click==8.1.3
+ # via flask
+flask==2.1.2
+ # via -r requirements.in
+importlib-metadata==4.11.3
+ # via flask
+itsdangerous==2.1.2
+ # via flask
+jinja2==3.1.2
+ # via flask
+markupsafe==2.1.1
+ # via jinja2
+wcag-contrast-ratio==0.9
+ # via -r requirements.in
+werkzeug==2.1.2
+ # via flask
+zipp==3.8.0
+ # via importlib-metadata
webapp/server.py (1963) → webapp/server.py (2403)
diff --git a/webapp/server.py b/webapp/server.py
index 2fba28c..98fda22 100755
--- a/webapp/server.py
+++ b/webapp/server.py
@@ -13,9 +13,12 @@ import wcag_contrast_ratio as contrast
app = Flask(__name__)
+VERSION = subprocess.check_output(["dominant_colours", "--version"]).decode("utf8")
+
+
@app.route("/")
def index():
- return render_template("index.html")
+ return render_template("index.html", version=VERSION)
@app.template_filter("foreground_colour")
@@ -27,9 +30,9 @@ def foreground_colour(hex_string):
ratio = contrast.rgb((red / 255, green / 255, blue / 255), (0, 0, 0))
if contrast.passes_AA(ratio):
- return '#000000'
+ return "#000000"
else:
- return '#FFFFFF'
+ return "#FFFFFF"
@app.route("/palette", methods=["POST"])
@@ -49,18 +52,35 @@ def get_palette():
# when running dominant_colours.
tmp_file.flush()
- result = subprocess.check_output(['dominant_colours', tmp_file.name, '--no-palette', '--max-colours=5'])
- colours = result.decode('utf8').strip().split('\n')
-
- with tempfile.NamedTemporaryFile(suffix='jpg') as thumbnail_file:
- subprocess.check_call(['convert', tmp_file.name, '-resize', '600x600', thumbnail_file.name])
+ result = subprocess.check_output(
+ ["dominant_colours", tmp_file.name, "--no-palette", "--max-colours=5"]
+ )
+ colours = result.decode("utf8").strip().split("\n")
+
+ with tempfile.NamedTemporaryFile(suffix="jpg") as thumbnail_file:
+ subprocess.check_call(
+ [
+ "convert",
+ tmp_file.name,
+ "-resize",
+ "600x600",
+ thumbnail_file.name,
+ ]
+ )
thumbnail_file.seek(0)
thumbnail = thumbnail_file.read()
- thumbnail_data_uri = (b'data:image/jpg;base64,' + base64.b64encode(thumbnail)).decode('ascii')
+ thumbnail_data_uri = (
+ b"data:image/jpg;base64," + base64.b64encode(thumbnail)
+ ).decode("ascii")
- return render_template('palette.html', colours=colours, thumbnail_data_uri=thumbnail_data_uri)
+ return render_template(
+ "palette.html",
+ colours=colours,
+ thumbnail_data_uri=thumbnail_data_uri,
+ version=VERSION,
+ )
if __name__ == "__main__":
- app.run(debug=True, host='0.0.0.0')
+ app.run(debug=True, host="0.0.0.0")
webapp/static/45degreee_fabric.png (0) → webapp/static/45degreee_fabric.png (153950)
diff --git a/webapp/static/45degreee_fabric.png b/webapp/static/45degreee_fabric.png
new file mode 100644
index 0000000..3c7fa3f
Binary files /dev/null and b/webapp/static/45degreee_fabric.png differ
webapp/static/style.css (0) → webapp/static/style.css (2097)
diff --git a/webapp/static/style.css b/webapp/static/style.css
new file mode 100644
index 0000000..5c7b01a
--- /dev/null
+++ b/webapp/static/style.css
@@ -0,0 +1,132 @@
+body {
+ margin: 0;
+ padding: 0;
+
+ /* Pattern from https://www.toptal.com/designers/subtlepatterns/awesome-pattern/ */
+ background-image: url('/static/45degreee_fabric.png');
+}
+
+main, footer {
+ max-width: 500px;
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+ padding: 5px;
+
+ font: 14pt Avenir, Arial, sans-serif;
+ color: #333;
+}
+
+footer {
+ font-size: 9pt;
+ color: #aaa;
+}
+
+a, a:visited {
+ color: #555;
+}
+
+footer a, footer a:visited {
+ color: #888;
+}
+
+a:hover {
+ background: #ccc;
+}
+
+#results {
+ display: grid;
+ grid-template-columns: 325px 70px auto;
+ grid-template-rows: repeat(5, 56px);
+ grid-gap: 5px;
+ height: 300px;
+
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.thumbnail {
+ grid-row: 1 / span 5;
+ grid-column: 1 / 3;
+ width: 300px;
+ height: 300px;
+}
+
+img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+}
+
+.sample {
+ grid-column: 1 / 2;
+}
+
+.label {
+ font-family: monospace;
+ height: 56px;
+ line-height: 56px;
+ text-align: left;
+}
+
+.sample {
+ width: 56px;
+ height: 56px;
+ grid-column: 2 / 3;
+}
+
+.label {
+ grid-column: 3 / 3;
+}
+
+#label_1, #sample_1 { grid-row: 1 / 5; }
+#label_2, #sample_2 { grid-row: 2 / 5; }
+#label_3, #sample_3 { grid-row: 3 / 5; }
+#label_4, #sample_4 { grid-row: 4 / 5; }
+#label_5, #sample_5 { grid-row: 5 / 5; }
+
+@media screen and (max-width: 600px) {
+ .thumbnail {
+ width: 300px;
+ height: 230px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+
+ #results {
+ grid-template-columns: 42px auto;
+ width: 300px;
+ grid-template-rows: 240px repeat(5, 42px);
+ grid-row-gap: 10px;
+ height: auto;
+ }
+
+ .thumbnail {
+ grid-column: 1 / span 2;
+ grid-row:1 / 6;
+ }
+
+ .sample {
+ grid-column: 1 / 2;
+ }
+
+ .label {
+ grid-column: 2 / 2;
+ }
+
+ #label_1, #sample_1 { grid-row: 2 / 6; }
+ #label_2, #sample_2 { grid-row: 3 / 6; }
+ #label_3, #sample_3 { grid-row: 4 / 6; }
+ #label_4, #sample_4 { grid-row: 5 / 6; }
+ #label_5, #sample_5 { grid-row: 6 / 6; }
+
+ .label {
+ height: 42px;
+ line-height: 42px;
+ }
+
+ .sample {
+ width: 42px;
+ height: 42px;
+ }
+}
webapp/templates/base.html (0) → webapp/templates/base.html (734)
diff --git a/webapp/templates/base.html b/webapp/templates/base.html
new file mode 100644
index 0000000..9015714
--- /dev/null
+++ b/webapp/templates/base.html
@@ -0,0 +1,26 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
+
+ <link rel="stylesheet" href="/static/style.css">
+
+ <title>dominant colours</title>
+ </head>
+ <body>
+ <main>
+ <h2>find the dominant colours in an image</h2>
+ {% block content %}
+ {% endblock %}
+ </main>
+ <footer>
+ made with <span class="heart">❤</span> by <a href="https://alexwlchan.net">alexwlchan</a>
+ ·
+ {{ version }}
+ ·
+ code on <a href="https://github.com/alexwlchan/dominant_colours/tree/main/webapp">github</a>
+ </div>
+ </footer>
+ </body>
+</html>
\ No newline at end of file
webapp/templates/index.html (408) → webapp/templates/index.html (282)
diff --git a/webapp/templates/index.html b/webapp/templates/index.html
index 8cff40c..82c6be1 100644
--- a/webapp/templates/index.html
+++ b/webapp/templates/index.html
@@ -1,15 +1,11 @@
-<html>
-<head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
+{% extends "base.html" %}
-</head>
- <body>
- <form action = "/palette" method = "POST"
- enctype = "multipart/form-data">
- <input type = "file" name = "file" />
- <input type = "submit"/>
- </form>
- </body>
-</html>
\ No newline at end of file
+{% block content %}
+ <p>upload an image to analyse:</p>
+
+ <form action="/palette" method="POST"
+ enctype="multipart/form-data">
+ <input type="file" name="file" accept=".gif,.jpg,.jpeg,.png"/>
+ <input type="submit"/>
+ </form>
+{% endblock %}
webapp/templates/palette.html (3058) → webapp/templates/palette.html (416)
diff --git a/webapp/templates/palette.html b/webapp/templates/palette.html
index 057fbe2..85ec9dc 100644
--- a/webapp/templates/palette.html
+++ b/webapp/templates/palette.html
@@ -1,138 +1,6 @@
-<head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
+{% extends "base.html" %}
-</head>
-
-<h1>dominant colours</h1>
-
- <style>
-/* .colour {
- width: calc(250px - 1em - .5em);
-/* text-align: center;*/
- padding: 5px;
-
-/* margin: .25em;*/
-/* border-radius: 5px;*/
-
-
-/* margin-left: auto;*/
-/* margin-right: auto;*/
- }*/
-
- main {
-/* max-width: 700px;*/
-/* margin-left: auto;*/
-/* margin-right: auto;*/
-/* text-align: center;*/
- }
-
- #results {
-/* margin-top: 1em;*/
- display: grid;
- grid-template-columns: 325px 48px auto;
- grid-template-rows: repeat(5, 48px);
- grid-gap: 15px;
- height: 300px;
- width: 600px;
- margin-left: auto;
- margin-right: auto;
- }
-
- .thumbnail {
-/* border: 4px solid #999;*/
- grid-row: 1 / span 5;
- grid-column: 1 / 3;
- width: 300px;
- height: 300px;
- background: #ddd;
-/* margin: -4px;*/
- }
-
- img {
- width: 100%;
- height: 100%;
- object-fit: contain;
- }
-
- .sample {
- grid-column: 1 / 2;
- }
-
- .label {
- font-family: monospace;
- font-size: 170%;
- height: 48px;
- line-height: 48px;
- }
-
- .sample {
- width: 48px;
- height: 48px;
- border: 2px solid black;
-/* margin: -2px;*/
- grid-column: 2 / 3;
- }
-
- .label {
- grid-column: 3 / 3;
- }
-
- #label_1, #sample_1 { grid-row: 1 / 5; }
- #label_2, #sample_2 { grid-row: 2 / 5; }
- #label_3, #sample_3 { grid-row: 3 / 5; }
- #label_4, #sample_4 { grid-row: 4 / 5; }
- #label_5, #sample_5 { grid-row: 5 / 5; }
-
- @media screen and (max-width: 600px) {
- .thumbnail {
- width: 300px;
- height: 230px;
- margin-left: auto;
- margin-right: auto;
- }
-
- #results {
- grid-template-columns: 42px auto;
- width: 300px;
- grid-template-rows: 240px repeat(5, 42px);
- grid-row-gap: 10px;
- height: auto;
- }
-
- .thumbnail {
- grid-column: 1 / span 2;
- grid-row:1 / 6;
- }
-
- .sample {
- grid-column: 1 / 2;
- }
-
- .label {
- grid-column: 2 / 2;
- }
-
- #label_1, #sample_1 { grid-row: 2 / 6; }
- #label_2, #sample_2 { grid-row: 3 / 6; }
- #label_3, #sample_3 { grid-row: 4 / 6; }
- #label_4, #sample_4 { grid-row: 5 / 6; }
- #label_5, #sample_5 { grid-row: 6 / 6; }
-
- .label {
- height: 42px;
- line-height: 42px;
- }
-
- .sample {
- width: 42px;
- height: 42px;
- }
- }
- </style>
-
-<main>
+{% block content %}
<div id="results">
<div class="thumbnail">
<img src="{{ thumbnail_data_uri }}">
@@ -144,5 +12,4 @@
</div>
<p><a href="/">try another image</a></p>
-</main>
-
+{% endblock %}