by3axap commited on
Commit
1883218
·
verified ·
1 Parent(s): ec077f7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -29
app.py CHANGED
@@ -35,16 +35,14 @@ def generate():
35
  gap_y = float(request.form.get('gap_y', 0))
36
  shift_stagger = float(request.form.get('shift_stagger', 0))
37
  base_scale = float(request.form.get('base_scale', 1.0))
 
 
38
  growth = float(request.form.get('growth', 0))
39
  growth_type = request.form.get('growth_type', 'sine')
 
 
40
  invert_mode = request.form.get('invert') == 'true'
41
 
42
- # --- Параметры холста ---
43
- canvas_w = 1400
44
- canvas_h = 900
45
- step = canvas_w / density
46
- rows = math.ceil(canvas_h / step)
47
-
48
  # --- Обработка SVG шейпа ---
49
  svg_file = request.files.get('shape_svg')
50
  if svg_file and svg_file.filename != '':
@@ -52,69 +50,104 @@ def generate():
52
  else:
53
  symbol_content, v_box = ('<rect width="100" height="100" fill="black"/>', "0 0 100 100")
54
 
 
 
 
 
55
  vb_parts = [float(x) for x in v_box.split()]
56
  vb_w, vb_h = vb_parts[2], vb_parts[3]
57
 
58
- # --- Обработка Растрового Изображения (ИСПРАВЛЕНО) ---
 
 
 
 
 
 
 
 
 
 
 
59
  raster_file = request.files.get('raster_image')
60
  pixel_map = None
61
 
62
  if raster_file and raster_file.filename != '':
63
  try:
64
  img = Image.open(raster_file)
65
- # 1. Сначала приводим пропорции фото к пропорциям холста (Crop center)
66
- img = ImageOps.fit(img, (canvas_w, canvas_h), method=Image.Resampling.LANCZOS)
67
- # 2. Переводим в ч/б
68
  img = ImageOps.grayscale(img)
69
- # 3. Сжимаем до размеров сетки
70
  img = img.resize((density, rows), resample=Image.Resampling.BILINEAR)
71
  pixel_map = img.load()
72
  except Exception as e:
73
  print(f"Image Error: {e}")
 
74
 
75
  # --- Генерация SVG ---
76
  body = []
77
- cell_w_max = step * (1.0 - gap_x)
78
- cell_h_max = step * (1.0 - gap_y)
79
-
80
  for r in range(rows):
 
81
  row_shift = (r * shift_stagger * step)
 
82
  for c in range(density):
83
  grid_x = (c * step + row_shift) % canvas_w
84
  grid_y = r * step
85
 
86
- mod = 1.0
 
87
  if pixel_map:
88
- brightness = pixel_map[min(c, density-1), min(r, rows-1)] / 255.0
89
- target_scale = brightness if invert_mode else (1.0 - brightness)
 
 
 
 
 
 
 
 
 
 
 
 
90
  if growth > 0:
91
- target_scale = min(1.0, max(0.0, target_scale * (1.0 + growth)))
92
- mod = target_scale
 
 
 
 
93
  else:
 
94
  wave_norm = 0
95
  if growth_type == 'sine':
96
  wave_norm = (math.sin(c * 0.3 + r * 0.3) + 1) / 2
97
  elif growth_type == 'linear':
98
  wave_norm = c / (density - 1) if density > 1 else 0
99
- mod = max(0, 1.0 - (wave_norm * growth))
 
 
 
 
 
100
 
101
- # Равномерное масштабирование символа
102
- content_w = cell_w_max * base_scale * mod
103
- content_h = cell_h_max * base_scale * mod # Высота теперь тоже зависит от mod для пропорций
104
 
105
  if content_w < 0.1 or content_h < 0.1:
106
  continue
107
 
108
- cx = grid_x + step/2
109
- cy = grid_y + step/2
110
 
111
- # Масштабируем так, чтобы вписать в ячейку пропорционально
112
- ratio = min(content_w / vb_w, content_h / vb_h)
113
 
114
- transform = f'translate({cx:.2f} {cy:.2f}) scale({ratio:.4f}) translate({-vb_w/2:.2f} {-vb_h/2:.2f})'
 
115
  body.append(f'<g transform="{transform}">{symbol_content}</g>')
116
 
117
- return f'<svg xmlns="http://www.w3.org/2000/svg" width="{canvas_w}" height="{canvas_h}" viewBox="0 0 {canvas_w} {canvas_h}" style="background:white;">{"".join(body)}</svg>'
118
 
119
  except Exception as e:
120
  return f'<svg width="800" height="200"><text y="50" fill="red" font-size="20">Error: {str(e)}</text></svg>', 200
 
35
  gap_y = float(request.form.get('gap_y', 0))
36
  shift_stagger = float(request.form.get('shift_stagger', 0))
37
  base_scale = float(request.form.get('base_scale', 1.0))
38
+
39
+ # Growth / Contrast
40
  growth = float(request.form.get('growth', 0))
41
  growth_type = request.form.get('growth_type', 'sine')
42
+
43
+ # Новая опция инверсии (если чекбокс отмечен, придет 'true')
44
  invert_mode = request.form.get('invert') == 'true'
45
 
 
 
 
 
 
 
46
  # --- Обработка SVG шейпа ---
47
  svg_file = request.files.get('shape_svg')
48
  if svg_file and svg_file.filename != '':
 
50
  else:
51
  symbol_content, v_box = ('<rect width="100" height="100" fill="black"/>', "0 0 100 100")
52
 
53
+ if request.form.get('current_svg_symbol'):
54
+ symbol_content = request.form.get('current_svg_symbol')
55
+ v_box = request.form.get('current_vbox', "0 0 100 100")
56
+
57
  vb_parts = [float(x) for x in v_box.split()]
58
  vb_w, vb_h = vb_parts[2], vb_parts[3]
59
 
60
+ # --- Параметры холста ---
61
+ canvas_w = 1400
62
+ canvas_h = 900
63
+ step = canvas_w / density
64
+ rows = math.ceil(canvas_h / step)
65
+
66
+ cell_w_max = step * (1.0 - gap_x)
67
+ cell_h_max = step * (1.0 - gap_y)
68
+ offset_x_base = (step - cell_w_max) / 2
69
+ offset_y_base = (step - cell_h_max) / 2
70
+
71
+ # --- Обработка Растрового Изображения ---
72
  raster_file = request.files.get('raster_image')
73
  pixel_map = None
74
 
75
  if raster_file and raster_file.filename != '':
76
  try:
77
  img = Image.open(raster_file)
 
 
 
78
  img = ImageOps.grayscale(img)
 
79
  img = img.resize((density, rows), resample=Image.Resampling.BILINEAR)
80
  pixel_map = img.load()
81
  except Exception as e:
82
  print(f"Image Error: {e}")
83
+ pixel_map = None
84
 
85
  # --- Генерация SVG ---
86
  body = []
 
 
 
87
  for r in range(rows):
88
+ # Stagger Shift (сдвиг рядов)
89
  row_shift = (r * shift_stagger * step)
90
+
91
  for c in range(density):
92
  grid_x = (c * step + row_shift) % canvas_w
93
  grid_y = r * step
94
 
95
+ mod_w = 1.0
96
+
97
  if pixel_map:
98
+ safe_c = min(c, density-1)
99
+ safe_r = min(r, rows-1)
100
+ brightness = pixel_map[safe_c, safe_r] / 255.0
101
+
102
+ # Логика инверсии
103
+ if invert_mode:
104
+ # Инверсия: Белое (1.0) -> Scale 1.0 (Большое), Черное -> 0
105
+ target_scale = brightness
106
+ else:
107
+ # Стандарт: Черное (0.0) -> Scale 1.0 (Большое), Белое -> 0
108
+ target_scale = 1.0 - brightness
109
+
110
+ # Growth slider работает как Контраст/Усиление
111
+ # Простая формула усиления эффекта
112
  if growth > 0:
113
+ # Упрощенная гамма-коррекция или мультипликатор для контраста
114
+ target_scale = target_scale * (1.0 + growth)
115
+ target_scale = min(1.0, max(0.0, target_scale))
116
+
117
+ mod_w = target_scale
118
+
119
  else:
120
+ # [Math Logic] (fallback без картинки)
121
  wave_norm = 0
122
  if growth_type == 'sine':
123
  wave_norm = (math.sin(c * 0.3 + r * 0.3) + 1) / 2
124
  elif growth_type == 'linear':
125
  wave_norm = c / (density - 1) if density > 1 else 0
126
+ elif growth_type == 'steps':
127
+ num_steps = 5
128
+ wave_norm = math.floor(c / (density / num_steps)) / (num_steps - 1) if density > 1 else 0
129
+
130
+ # Здесь invert тоже можно применить, если нужно, но оставим как было
131
+ mod_w = max(0, 1.0 - (wave_norm * growth))
132
 
133
+ # Итоговые размеры
134
+ content_w = cell_w_max * base_scale * mod_w
135
+ content_h = cell_h_max * base_scale
136
 
137
  if content_w < 0.1 or content_h < 0.1:
138
  continue
139
 
140
+ cx = grid_x + offset_x_base + cell_w_max / 2
141
+ cy = grid_y + offset_y_base + cell_h_max / 2
142
 
143
+ scale_x = content_w / vb_w
144
+ scale_y = content_h / vb_h
145
 
146
+ # Убран rotate из transform
147
+ transform = f'translate({cx:.2f} {cy:.2f}) scale({scale_x:.4f} {scale_y:.4f}) translate({-vb_w/2:.2f} {-vb_h/2:.2f})'
148
  body.append(f'<g transform="{transform}">{symbol_content}</g>')
149
 
150
+ return f'<svg xmlns="http://www.w3.org/2000/svg" width="{canvas_w}" height="{canvas_h}" viewBox="0 0 {canvas_w} {canvas_h}">{"".join(body)}</svg>'
151
 
152
  except Exception as e:
153
  return f'<svg width="800" height="200"><text y="50" fill="red" font-size="20">Error: {str(e)}</text></svg>', 200