sayedM commited on
Commit
ae1988a
·
verified ·
1 Parent(s): b65e685

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -32
app.py CHANGED
@@ -15,87 +15,79 @@ def modern_to_nokia_pil(
15
  gamma=1.3,
16
  add_date_stamp=True,
17
  ):
18
- # Ensure RGB
19
  img = img.convert("RGB")
20
 
21
- # --- Crop to 4:3 like old phones ---
22
  w, h = img.size
23
  target_ratio = 4 / 3
24
  current_ratio = w / h
25
 
26
  if current_ratio > target_ratio:
27
- # too wide: crop width
28
  new_w = int(h * target_ratio)
29
  left = (w - new_w) // 2
30
  img = img.crop((left, 0, left + new_w, h))
31
  else:
32
- # too tall: crop height
33
  new_h = int(w / target_ratio)
34
  top = (h - new_h) // 2
35
  img = img.crop((0, top, w, top + new_h))
36
 
37
- # --- Resize down to ~0.3 MP (640x480) ---
38
  img = img.resize((640, 480), resample=Image.BILINEAR)
39
 
40
- # --- Slight blur for soft lens ---
41
  img = img.filter(ImageFilter.GaussianBlur(radius=blur_radius))
42
 
43
- # --- Reduce color depth (posterization) ---
44
  arr = np.array(img, dtype=np.uint8)
45
- if color_levels < 2:
46
- color_levels = 2
47
- step = max(1, 256 // int(color_levels)) # step size
48
  arr = (arr // step) * step
49
  img = Image.fromarray(arr, mode="RGB")
50
 
51
- # --- Add noise ---
52
  arr = np.array(img, dtype=np.int16)
53
  noise = np.random.normal(0, noise_std, arr.shape)
54
- arr = arr + noise
55
- arr = np.clip(arr, 0, 255).astype(np.uint8)
56
  img = Image.fromarray(arr, mode="RGB")
57
 
58
- # --- Crush dynamic range (gamma curve) ---
59
  arr = np.array(img, dtype=np.float32) / 255.0
60
- arr = np.power(arr, gamma) # gamma >1 = darker mids
61
  arr = np.clip(arr * 255, 0, 255).astype(np.uint8)
62
  img = Image.fromarray(arr, mode="RGB")
63
 
64
- # --- Optional yellow date stamp in corner ---
65
  if add_date_stamp:
66
  draw = ImageDraw.Draw(img)
67
  font = ImageFont.load_default()
68
- now = datetime.datetime.now()
69
- text = now.strftime("%d-%m-%y %H:%M") # Nokia-style
70
- # text size
71
- text_w, text_h = draw.textsize(text, font=font)
 
 
 
72
  margin = 4
73
  x = img.width - text_w - margin
74
  y = img.height - text_h - margin
75
- # black box behind text
76
  draw.rectangle(
77
  [x - 2, y - 2, x + text_w + 2, y + text_h + 2],
78
  fill=(0, 0, 0),
79
  )
80
- # yellow-ish text
81
  draw.text((x, y), text, font=font, fill=(255, 255, 0))
82
 
83
- # --- Save with low JPEG quality to get artifacts ---
84
  buffer = io.BytesIO()
85
- img.save(
86
- buffer,
87
- format="JPEG",
88
- quality=int(jpeg_quality),
89
- optimize=False,
90
- progressive=False,
91
- )
92
  buffer.seek(0)
93
  img = Image.open(buffer)
94
 
95
  return img
96
 
97
 
98
- def convert_fn(image, jpeg_quality, noise_std, color_levels, blur_radius, gamma, add_date_stamp):
 
99
  if image is None:
100
  return None
101
  return modern_to_nokia_pil(
@@ -125,6 +117,5 @@ demo = gr.Interface(
125
  description="Upload a modern photo and turn it into an old-school 0.3 MP Nokia-style photo.",
126
  )
127
 
128
-
129
  if __name__ == "__main__":
130
  demo.launch()
 
15
  gamma=1.3,
16
  add_date_stamp=True,
17
  ):
 
18
  img = img.convert("RGB")
19
 
20
+ # --- Crop to 4:3 ---
21
  w, h = img.size
22
  target_ratio = 4 / 3
23
  current_ratio = w / h
24
 
25
  if current_ratio > target_ratio:
 
26
  new_w = int(h * target_ratio)
27
  left = (w - new_w) // 2
28
  img = img.crop((left, 0, left + new_w, h))
29
  else:
 
30
  new_h = int(w / target_ratio)
31
  top = (h - new_h) // 2
32
  img = img.crop((0, top, w, top + new_h))
33
 
34
+ # --- Resize to 640×480 ---
35
  img = img.resize((640, 480), resample=Image.BILINEAR)
36
 
37
+ # --- Blur ---
38
  img = img.filter(ImageFilter.GaussianBlur(radius=blur_radius))
39
 
40
+ # --- Posterize (reduce color depth) ---
41
  arr = np.array(img, dtype=np.uint8)
42
+ step = max(1, 256 // int(color_levels))
 
 
43
  arr = (arr // step) * step
44
  img = Image.fromarray(arr, mode="RGB")
45
 
46
+ # --- Noise ---
47
  arr = np.array(img, dtype=np.int16)
48
  noise = np.random.normal(0, noise_std, arr.shape)
49
+ arr = np.clip(arr + noise, 0, 255).astype(np.uint8)
 
50
  img = Image.fromarray(arr, mode="RGB")
51
 
52
+ # --- Gamma curve ---
53
  arr = np.array(img, dtype=np.float32) / 255.0
54
+ arr = np.power(arr, gamma)
55
  arr = np.clip(arr * 255, 0, 255).astype(np.uint8)
56
  img = Image.fromarray(arr, mode="RGB")
57
 
58
+ # --- Date stamp (fixed for Pillow >= 10) ---
59
  if add_date_stamp:
60
  draw = ImageDraw.Draw(img)
61
  font = ImageFont.load_default()
62
+ text = datetime.datetime.now().strftime("%d-%m-%y %H:%M")
63
+
64
+ # NEW SAFE SIZE METHOD
65
+ bbox = draw.textbbox((0, 0), text, font=font)
66
+ text_w = bbox[2] - bbox[0]
67
+ text_h = bbox[3] - bbox[1]
68
+
69
  margin = 4
70
  x = img.width - text_w - margin
71
  y = img.height - text_h - margin
72
+
73
  draw.rectangle(
74
  [x - 2, y - 2, x + text_w + 2, y + text_h + 2],
75
  fill=(0, 0, 0),
76
  )
 
77
  draw.text((x, y), text, font=font, fill=(255, 255, 0))
78
 
79
+ # --- JPEG compression ---
80
  buffer = io.BytesIO()
81
+ img.save(buffer, format="JPEG", quality=int(jpeg_quality),
82
+ optimize=False, progressive=False)
 
 
 
 
 
83
  buffer.seek(0)
84
  img = Image.open(buffer)
85
 
86
  return img
87
 
88
 
89
+ def convert_fn(image, jpeg_quality, noise_std, color_levels,
90
+ blur_radius, gamma, add_date_stamp):
91
  if image is None:
92
  return None
93
  return modern_to_nokia_pil(
 
117
  description="Upload a modern photo and turn it into an old-school 0.3 MP Nokia-style photo.",
118
  )
119
 
 
120
  if __name__ == "__main__":
121
  demo.launch()