From bfe45f50a83e5c991848c64f1f0b0c505678f427 Mon Sep 17 00:00:00 2001 From: Richard Du Date: Mon, 2 Jan 2017 21:51:36 -0500 Subject: [PATCH] Add Flask web framework --- .gitignore | 2 + app.py | 73 +++++ static/css/normalize.css | 427 +++++++++++++++++++++++++++++ static/css/skeleton.css | 418 ++++++++++++++++++++++++++++ static/img/deeparch.png | Bin 0 -> 23744 bytes templates/_image_segmentation.html | 26 ++ templates/_style_transfer.html | 1 + templates/index.html | 101 +++++++ tmp/.gitignore | 2 + 9 files changed, 1050 insertions(+) create mode 100644 .gitignore create mode 100644 app.py create mode 100644 static/css/normalize.css create mode 100644 static/css/skeleton.css create mode 100644 static/img/deeparch.png create mode 100644 templates/_image_segmentation.html create mode 100644 templates/_style_transfer.html create mode 100644 templates/index.html create mode 100644 tmp/.gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61f8f56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyc +venv \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..4fa9e50 --- /dev/null +++ b/app.py @@ -0,0 +1,73 @@ +import random +import string +import os +from flask import Flask, request, redirect, render_template, send_from_directory, jsonify +from werkzeug.utils import secure_filename +from PIL import Image, ImageFilter + +UPLOAD_FOLDER = './tmp' +ALLOWED_EXTENSIONS = set(['pdf', 'png', 'jpg', 'jpeg']) + +app = Flask(__name__) +app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER + +def allowed_file(filename): + return '.' in filename and \ + filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + +def file_extension(filename): + if '.' in filename: + return filename.rsplit('.', 1)[1].lower() + else: + return None + +def file_name_generator(size=10, chars=string.ascii_uppercase): + return ''.join(random.choice(chars) for _ in range(size)) + +def color_generator(): + return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) + +@app.route('/') +def index(): + return render_template('index.html') + +@app.route('/uploads/') +def uploaded_file(filename): + return send_from_directory(app.config['UPLOAD_FOLDER'], filename) + +@app.route('/_image_segmentation', methods=['POST']) +def upload_file(): + # check if the post request has the file part + if 'file' not in request.files: + flash('No file part') + return redirect(request.url) + file = request.files['file'] + # if user does not select file, browser also + # submit a empty part without filename + if file.filename == '': + flash('No selected file') + return redirect(request.url) + if file and allowed_file(file.filename): + segments = [] + original_image = secure_filename(file.filename) + extension = file_extension(original_image) + file.save(os.path.join(app.config['UPLOAD_FOLDER'], original_image)) + # do segmentation, save images to temp folder + for i in xrange(5): + filename = file_name_generator() + '.' + extension + image = Image.new("RGB", (400, 400), color_generator()) + image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) + segments.append(filename) + # return urls to segmented images + return render_template('_image_segmentation.html', original_image=original_image, segments=segments) + +@app.route('/_style_transfer', methods=['POST']) +def style_transfer(): + # parse what the user wants to do to each segment of the image + d = request.get_json() + # compute the final image + # for file, style in d.iteritems(): + filename = file_name_generator() + '.jpg' + image = Image.new("RGB", (400, 400), color_generator()) + image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) + return render_template('_style_transfer.html', new_image=filename) \ No newline at end of file diff --git a/static/css/normalize.css b/static/css/normalize.css new file mode 100644 index 0000000..81c6f31 --- /dev/null +++ b/static/css/normalize.css @@ -0,0 +1,427 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} \ No newline at end of file diff --git a/static/css/skeleton.css b/static/css/skeleton.css new file mode 100644 index 0000000..f28bf6c --- /dev/null +++ b/static/css/skeleton.css @@ -0,0 +1,418 @@ +/* +* Skeleton V2.0.4 +* Copyright 2014, Dave Gamache +* www.getskeleton.com +* Free to use under the MIT license. +* http://www.opensource.org/licenses/mit-license.php +* 12/29/2014 +*/ + + +/* Table of contents +–––––––––––––––––––––––––––––––––––––––––––––––––– +- Grid +- Base Styles +- Typography +- Links +- Buttons +- Forms +- Lists +- Code +- Tables +- Spacing +- Utilities +- Clearing +- Media Queries +*/ + + +/* Grid +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.container { + position: relative; + width: 100%; + max-width: 960px; + margin: 0 auto; + padding: 0 20px; + box-sizing: border-box; } +.column, +.columns { + width: 100%; + float: left; + box-sizing: border-box; } + +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 85%; + padding: 0; } +} + +/* For devices larger than 550px */ +@media (min-width: 550px) { + .container { + width: 80%; } + .column, + .columns { + margin-left: 4%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } + + .one.column, + .one.columns { width: 4.66666666667%; } + .two.columns { width: 13.3333333333%; } + .three.columns { width: 22%; } + .four.columns { width: 30.6666666667%; } + .five.columns { width: 39.3333333333%; } + .six.columns { width: 48%; } + .seven.columns { width: 56.6666666667%; } + .eight.columns { width: 65.3333333333%; } + .nine.columns { width: 74.0%; } + .ten.columns { width: 82.6666666667%; } + .eleven.columns { width: 91.3333333333%; } + .twelve.columns { width: 100%; margin-left: 0; } + + .one-third.column { width: 30.6666666667%; } + .two-thirds.column { width: 65.3333333333%; } + + .one-half.column { width: 48%; } + + /* Offsets */ + .offset-by-one.column, + .offset-by-one.columns { margin-left: 8.66666666667%; } + .offset-by-two.column, + .offset-by-two.columns { margin-left: 17.3333333333%; } + .offset-by-three.column, + .offset-by-three.columns { margin-left: 26%; } + .offset-by-four.column, + .offset-by-four.columns { margin-left: 34.6666666667%; } + .offset-by-five.column, + .offset-by-five.columns { margin-left: 43.3333333333%; } + .offset-by-six.column, + .offset-by-six.columns { margin-left: 52%; } + .offset-by-seven.column, + .offset-by-seven.columns { margin-left: 60.6666666667%; } + .offset-by-eight.column, + .offset-by-eight.columns { margin-left: 69.3333333333%; } + .offset-by-nine.column, + .offset-by-nine.columns { margin-left: 78.0%; } + .offset-by-ten.column, + .offset-by-ten.columns { margin-left: 86.6666666667%; } + .offset-by-eleven.column, + .offset-by-eleven.columns { margin-left: 95.3333333333%; } + + .offset-by-one-third.column, + .offset-by-one-third.columns { margin-left: 34.6666666667%; } + .offset-by-two-thirds.column, + .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } + + .offset-by-one-half.column, + .offset-by-one-half.columns { margin-left: 52%; } + +} + + +/* Base Styles +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +/* NOTE +html is set to 62.5% so that all the REM measurements throughout Skeleton +are based on 10px sizing. So basically 1.5rem = 15px :) */ +html { + font-size: 62.5%; } +body { + font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ + line-height: 1.6; + font-weight: 400; + font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #222; } + + +/* Typography +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 2rem; + font-weight: 300; } +h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} +h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } +h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } +h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } +h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } +h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } + +/* Larger than phablet */ +@media (min-width: 550px) { + h1 { font-size: 5.0rem; } + h2 { font-size: 4.2rem; } + h3 { font-size: 3.6rem; } + h4 { font-size: 3.0rem; } + h5 { font-size: 2.4rem; } + h6 { font-size: 1.5rem; } +} + +p { + margin-top: 0; } + + +/* Links +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +a { + color: #1EAEDB; } +a:hover { + color: #0FA0CE; } + + +/* Buttons +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.button, +button, +input[type="submit"], +input[type="reset"], +input[type="button"] { + display: inline-block; + height: 38px; + padding: 0 30px; + color: #555; + text-align: center; + font-size: 11px; + font-weight: 600; + line-height: 38px; + letter-spacing: .1rem; + text-transform: uppercase; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border-radius: 4px; + border: 1px solid #bbb; + cursor: pointer; + box-sizing: border-box; } +.button:hover, +button:hover, +input[type="submit"]:hover, +input[type="reset"]:hover, +input[type="button"]:hover, +.button:focus, +button:focus, +input[type="submit"]:focus, +input[type="reset"]:focus, +input[type="button"]:focus { + color: #333; + border-color: #888; + outline: 0; } +.button.button-primary, +button.button-primary, +input[type="submit"].button-primary, +input[type="reset"].button-primary, +input[type="button"].button-primary { + color: #FFF; + background-color: #33C3F0; + border-color: #33C3F0; } +.button.button-primary:hover, +button.button-primary:hover, +input[type="submit"].button-primary:hover, +input[type="reset"].button-primary:hover, +input[type="button"].button-primary:hover, +.button.button-primary:focus, +button.button-primary:focus, +input[type="submit"].button-primary:focus, +input[type="reset"].button-primary:focus, +input[type="button"].button-primary:focus { + color: #FFF; + background-color: #1EAEDB; + border-color: #1EAEDB; } + + +/* Forms +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea, +select { + height: 38px; + padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ + background-color: #fff; + border: 1px solid #D1D1D1; + border-radius: 4px; + box-shadow: none; + box-sizing: border-box; } +/* Removes awkward default styles on some inputs for iOS */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; } +textarea { + min-height: 65px; + padding-top: 6px; + padding-bottom: 6px; } +input[type="email"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +input[type="text"]:focus, +input[type="tel"]:focus, +input[type="url"]:focus, +input[type="password"]:focus, +textarea:focus, +select:focus { + border: 1px solid #33C3F0; + outline: 0; } +label, +legend { + display: block; + margin-bottom: .5rem; + font-weight: 600; } +fieldset { + padding: 0; + border-width: 0; } +input[type="checkbox"], +input[type="radio"] { + display: inline; } +label > .label-body { + display: inline-block; + margin-left: .5rem; + font-weight: normal; } + + +/* Lists +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +ul { + list-style: circle inside; } +ol { + list-style: decimal inside; } +ol, ul { + padding-left: 0; + margin-top: 0; } +ul ul, +ul ol, +ol ol, +ol ul { + margin: 1.5rem 0 1.5rem 3rem; + font-size: 90%; } +li { + margin-bottom: 1rem; } + + +/* Code +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +code { + padding: .2rem .5rem; + margin: 0 .2rem; + font-size: 90%; + white-space: nowrap; + background: #F1F1F1; + border: 1px solid #E1E1E1; + border-radius: 4px; } +pre > code { + display: block; + padding: 1rem 1.5rem; + white-space: pre; } + + +/* Tables +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +th, +td { + padding: 12px 15px; + text-align: left; + border-bottom: 1px solid #E1E1E1; } +th:first-child, +td:first-child { + padding-left: 0; } +th:last-child, +td:last-child { + padding-right: 0; } + + +/* Spacing +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +button, +.button { + margin-bottom: 1rem; } +input, +textarea, +select, +fieldset { + margin-bottom: 1.5rem; } +pre, +blockquote, +dl, +figure, +table, +p, +ul, +ol, +form { + margin-bottom: 2.5rem; } + + +/* Utilities +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.u-full-width { + width: 100%; + box-sizing: border-box; } +.u-max-full-width { + max-width: 100%; + box-sizing: border-box; } +.u-pull-right { + float: right; } +.u-pull-left { + float: left; } + + +/* Misc +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +hr { + margin-top: 3rem; + margin-bottom: 3.5rem; + border-width: 0; + border-top: 1px solid #E1E1E1; } + + +/* Clearing +–––––––––––––––––––––––––––––––––––––––––––––––––– */ + +/* Self Clearing Goodness */ +.container:after, +.row:after, +.u-cf { + content: ""; + display: table; + clear: both; } + + +/* Media Queries +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +/* +Note: The best way to structure the use of media queries is to create the queries +near the relevant code. For example, if you wanted to change the styles for buttons +on small devices, paste the mobile query code up in the buttons section and style it +there. +*/ + + +/* Larger than mobile */ +@media (min-width: 400px) {} + +/* Larger than phablet (also point when grid becomes active) */ +@media (min-width: 550px) {} + +/* Larger than tablet */ +@media (min-width: 750px) {} + +/* Larger than desktop */ +@media (min-width: 1000px) {} + +/* Larger than Desktop HD */ +@media (min-width: 1200px) {} diff --git a/static/img/deeparch.png b/static/img/deeparch.png new file mode 100644 index 0000000000000000000000000000000000000000..5c6f0fd5d131ea375069988657bbf1117302f669 GIT binary patch literal 23744 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 +
+ +
+ +
+
+ {% for file in segments %} + +
+ + +
+ {% endfor %} +
+
+ +
+ +{% endblock %} \ No newline at end of file diff --git a/templates/_style_transfer.html b/templates/_style_transfer.html new file mode 100644 index 0000000..fd88976 --- /dev/null +++ b/templates/_style_transfer.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..1e7b9f5 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,101 @@ + + + + + + + + + + + +
+
+
+
+ + +
+
+
+
+ +
+
+ +
+
+ \ No newline at end of file diff --git a/tmp/.gitignore b/tmp/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/tmp/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file