-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
104 lines (79 loc) · 3.18 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import io
import os
import zipfile
from flask import Flask, render_template, request, send_file
from PIL import Image
app = Flask(__name__)
# Set the maximum file size (20MB)
app.config["MAX_CONTENT_LENGTH"] = 20 * 1024 * 1024 # 20MB
def is_image(file):
try:
with Image.open(file.stream) as img:
return img.format in ["JPEG", "PNG", "WEBP"]
except Exception:
return False
@app.route("/", methods=["GET", "POST"])
def upload_file():
if request.method == "POST":
files = request.files.getlist("file")
format = request.form.get("format", "webp").lower()
quality = int(request.form.get("quality", 80))
# Check file count
if len(files) > 5:
return render_template(
"index.html", error="You can only upload up to 5 images at a time."
)
# Check file size and type
for file in files:
if file.content_length > app.config["MAX_CONTENT_LENGTH"]:
return render_template(
"index.html", error="Each file must be less than 20MB in size."
)
if not is_image(file):
return render_template(
"index.html",
error="All files must be valid image formats (JPEG, PNG, or WEBP).",
)
if len(files) == 1:
file = files[0]
image = Image.open(file.stream)
output_io = io.BytesIO()
save_kwargs = {}
if format in ["jpeg", "webp"]:
save_kwargs["quality"] = quality
image.save(output_io, format=format.upper(), **save_kwargs)
output_io.seek(0)
original_filename = file.filename
basename, ext = os.path.splitext(original_filename)
new_filename = f"{basename}_converted.{format}"
return send_file(
output_io,
mimetype=f"image/{format}",
download_name=new_filename,
as_attachment=True,
)
elif len(files) > 1:
zip_output = io.BytesIO()
with zipfile.ZipFile(zip_output, "w") as zipf:
for file in files:
image = Image.open(file.stream)
output_io = io.BytesIO()
save_kwargs = {}
if format in ["jpeg", "webp"]:
save_kwargs["quality"] = quality
image.save(output_io, format=format.upper(), **save_kwargs)
output_io.seek(0)
original_filename = file.filename
basename, ext = os.path.splitext(original_filename)
new_filename = f"{basename}_converted.{format}"
zipf.writestr(new_filename, output_io.read())
zip_output.seek(0)
return send_file(
zip_output,
mimetype="application/zip",
download_name="converted_images.zip",
as_attachment=True,
)
return render_template("index.html")
if __name__ == "__main__":
app.run(port=int(os.environ.get("PORT", 8080)), host="0.0.0.0", debug=True)