dschandra commited on
Commit
a68943c
Β·
verified Β·
1 Parent(s): 1d618a9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -36
app.py CHANGED
@@ -2,8 +2,6 @@ import io
2
  from PIL import Image
3
  import gradio as gr
4
 
5
- ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "webp"}
6
-
7
  def get_file_size_label(size_bytes):
8
  if size_bytes < 1024 * 1024:
9
  return f"{size_bytes / 1024:.1f} KB"
@@ -13,7 +11,7 @@ def get_file_size_label(size_bytes):
13
  def compress_to_target(img, fmt, target_bytes):
14
  buf = io.BytesIO()
15
 
16
- # ---- PNG handling ----
17
  if fmt == "PNG":
18
  for level in range(1, 10):
19
  buf = io.BytesIO()
@@ -22,14 +20,31 @@ def compress_to_target(img, fmt, target_bytes):
22
  buf.seek(0)
23
  return buf, "PNG"
24
 
25
- # fallback to WEBP lossless
26
- buf = io.BytesIO()
27
- img.save(buf, format="WEBP", lossless=True, quality=100)
28
- if buf.tell() <= target_bytes:
29
- buf.seek(0)
30
- return buf, "WEBP"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- for q in range(95, 79, -5):
 
 
33
  buf = io.BytesIO()
34
  img.save(buf, format="WEBP", quality=q, method=6)
35
  if buf.tell() <= target_bytes:
@@ -39,23 +54,18 @@ def compress_to_target(img, fmt, target_bytes):
39
  buf.seek(0)
40
  return buf, "WEBP"
41
 
42
- # ---- JPEG / WEBP ----
43
- save_fmt = "JPEG" if fmt in ("JPEG", "JPG") else "WEBP"
44
-
45
- for q in range(95, 74, -2):
46
- buf = io.BytesIO()
47
- if save_fmt == "JPEG":
48
- img.save(buf, format="JPEG", quality=q, optimize=True,
49
- subsampling=0 if q >= 85 else 2)
50
- else:
51
- img.save(buf, format="WEBP", quality=q, method=6)
52
-
53
- if buf.tell() <= target_bytes:
54
- buf.seek(0)
55
- return buf, save_fmt
56
 
57
- buf.seek(0)
58
- return buf, save_fmt
59
 
60
 
61
  def process_image(file, target_value, unit):
@@ -64,31 +74,44 @@ def process_image(file, target_value, unit):
64
 
65
  try:
66
  img = Image.open(file)
67
- fmt = img.format or "JPEG"
68
 
69
- # normalize image mode
70
  if img.mode in ("RGBA", "LA", "P"):
71
  if fmt == "JPEG":
72
  background = Image.new("RGB", img.size, (255, 255, 255))
73
  if img.mode == "P":
74
  img = img.convert("RGBA")
75
- background.paste(img, mask=img.split()[-1] if img.mode in ("RGBA", "LA") else None)
 
 
 
76
  img = background
77
  elif img.mode not in ("RGB", "L"):
78
  img = img.convert("RGB")
79
 
80
- # original size
81
  original_buf = io.BytesIO()
82
- img.save(original_buf, format="PNG")
 
 
 
 
 
 
83
  original_size = original_buf.tell()
84
 
85
- target_bytes = int(target_value * 1024) if unit == "KB" else int(target_value * 1024 * 1024)
 
 
 
 
86
 
87
- # already small
88
  if target_bytes >= original_size:
89
  return img, f"βœ… Already optimized: {get_file_size_label(original_size)}"
90
 
91
- # compress
92
  compressed_buf, out_fmt = compress_to_target(img, fmt, target_bytes)
93
  compressed_size = compressed_buf.getbuffer().nbytes
94
 
@@ -98,7 +121,8 @@ def process_image(file, target_value, unit):
98
  result_msg = (
99
  f"πŸ“¦ Original: {get_file_size_label(original_size)}\n"
100
  f"πŸ—œοΈ Compressed: {get_file_size_label(compressed_size)}\n"
101
- f"πŸ’Ύ Saved: {pct:.1f}%"
 
102
  )
103
 
104
  return Image.open(compressed_buf), result_msg
@@ -110,7 +134,7 @@ def process_image(file, target_value, unit):
110
  # ---- UI ----
111
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
112
  gr.Markdown("# πŸ—œοΈ ImagePress β€” Smart Compressor")
113
- gr.Markdown("Compress images to target size **without visible quality loss**")
114
 
115
  with gr.Row():
116
  input_img = gr.Image(type="filepath", label="Upload Image")
 
2
  from PIL import Image
3
  import gradio as gr
4
 
 
 
5
  def get_file_size_label(size_bytes):
6
  if size_bytes < 1024 * 1024:
7
  return f"{size_bytes / 1024:.1f} KB"
 
11
  def compress_to_target(img, fmt, target_bytes):
12
  buf = io.BytesIO()
13
 
14
+ # ---- PNG (NO format change) ----
15
  if fmt == "PNG":
16
  for level in range(1, 10):
17
  buf = io.BytesIO()
 
20
  buf.seek(0)
21
  return buf, "PNG"
22
 
23
+ # If cannot reach target β†’ return best effort PNG
24
+ buf.seek(0)
25
+ return buf, "PNG"
26
+
27
+ # ---- JPEG ----
28
+ elif fmt in ("JPEG", "JPG"):
29
+ for q in range(95, 74, -2):
30
+ buf = io.BytesIO()
31
+ img.save(
32
+ buf,
33
+ format="JPEG",
34
+ quality=q,
35
+ optimize=True,
36
+ subsampling=0 if q >= 85 else 2
37
+ )
38
+ if buf.tell() <= target_bytes:
39
+ buf.seek(0)
40
+ return buf, "JPEG"
41
+
42
+ buf.seek(0)
43
+ return buf, "JPEG"
44
 
45
+ # ---- WEBP ----
46
+ elif fmt == "WEBP":
47
+ for q in range(95, 74, -2):
48
  buf = io.BytesIO()
49
  img.save(buf, format="WEBP", quality=q, method=6)
50
  if buf.tell() <= target_bytes:
 
54
  buf.seek(0)
55
  return buf, "WEBP"
56
 
57
+ # ---- fallback ----
58
+ else:
59
+ img = img.convert("RGB")
60
+ for q in range(95, 74, -2):
61
+ buf = io.BytesIO()
62
+ img.save(buf, format="JPEG", quality=q, optimize=True)
63
+ if buf.tell() <= target_bytes:
64
+ buf.seek(0)
65
+ return buf, "JPEG"
 
 
 
 
 
66
 
67
+ buf.seek(0)
68
+ return buf, "JPEG"
69
 
70
 
71
  def process_image(file, target_value, unit):
 
74
 
75
  try:
76
  img = Image.open(file)
77
+ fmt = (img.format or "JPEG").upper()
78
 
79
+ # Normalize mode
80
  if img.mode in ("RGBA", "LA", "P"):
81
  if fmt == "JPEG":
82
  background = Image.new("RGB", img.size, (255, 255, 255))
83
  if img.mode == "P":
84
  img = img.convert("RGBA")
85
+ background.paste(
86
+ img,
87
+ mask=img.split()[-1] if img.mode in ("RGBA", "LA") else None
88
+ )
89
  img = background
90
  elif img.mode not in ("RGB", "L"):
91
  img = img.convert("RGB")
92
 
93
+ # Original size
94
  original_buf = io.BytesIO()
95
+ if fmt == "PNG":
96
+ img.save(original_buf, format="PNG")
97
+ elif fmt == "WEBP":
98
+ img.save(original_buf, format="WEBP")
99
+ else:
100
+ img.save(original_buf, format="JPEG", quality=95)
101
+
102
  original_size = original_buf.tell()
103
 
104
+ target_bytes = (
105
+ int(target_value * 1024)
106
+ if unit == "KB"
107
+ else int(target_value * 1024 * 1024)
108
+ )
109
 
110
+ # If already small
111
  if target_bytes >= original_size:
112
  return img, f"βœ… Already optimized: {get_file_size_label(original_size)}"
113
 
114
+ # Compress
115
  compressed_buf, out_fmt = compress_to_target(img, fmt, target_bytes)
116
  compressed_size = compressed_buf.getbuffer().nbytes
117
 
 
121
  result_msg = (
122
  f"πŸ“¦ Original: {get_file_size_label(original_size)}\n"
123
  f"πŸ—œοΈ Compressed: {get_file_size_label(compressed_size)}\n"
124
+ f"πŸ’Ύ Saved: {pct:.1f}%\n"
125
+ f"πŸ“ Format: {out_fmt}"
126
  )
127
 
128
  return Image.open(compressed_buf), result_msg
 
134
  # ---- UI ----
135
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
136
  gr.Markdown("# πŸ—œοΈ ImagePress β€” Smart Compressor")
137
+ gr.Markdown("βœ” Preserves original format Β· βœ” No unwanted WEBP conversion")
138
 
139
  with gr.Row():
140
  input_img = gr.Image(type="filepath", label="Upload Image")