Skip to content

Commit 1bcef26

Browse files
Grzegorz Kocjangkocjan
authored andcommitted
Single spearker images fixes
1 parent adc09c7 commit 1bcef26

File tree

2 files changed

+50
-55
lines changed

2 files changed

+50
-55
lines changed

src/pyldz/hugo_generator.py

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -245,35 +245,19 @@ def create_featured_image(
245245
speakers,
246246
meetup,
247247
),
248-
(
249-
meetup_images_dir / "speaker_0-en-1x1.png",
250-
Language.EN,
251-
"1x1",
252-
[speakers[0]],
253-
meetup_speaker_0,
254-
),
255-
(
256-
meetup_images_dir / "speaker_1-en-1x1.png",
257-
Language.EN,
258-
"1x1",
259-
[speakers[1]],
260-
meetup_speaker_1,
261-
),
262-
(
263-
meetup_images_dir / "speaker_0-en-16x9.png",
264-
Language.EN,
265-
"16x9",
266-
[speakers[0]],
267-
meetup_speaker_0,
268-
),
269-
(
270-
meetup_images_dir / "speaker_1-en-16x9.png",
271-
Language.EN,
272-
"16x9",
273-
[speakers[1]],
274-
meetup_speaker_1,
275-
),
276248
]
249+
for ration in ["16x9", "4x5", "1x1"]:
250+
for x in range(len(meetup.talks)):
251+
lang = meetup.language
252+
images_variants.append(
253+
(
254+
meetup_images_dir / f"speaker_{x}-{lang.value}-{ration}.png",
255+
lang,
256+
ration,
257+
[speakers[x]],
258+
meetup.model_copy(update={"talks": [meetup.talks[x]]}),
259+
)
260+
)
277261

278262
for variant in images_variants:
279263
image_path, language, aspect_ratio, image_speakers, image_meetup = variant

src/pyldz/image_generator.py

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class MeetupImageGenerator:
2626
- data (YYYY MM DD) w żółtym akcencie + poniżej "DZIEŃ, HH:MM"
2727
- prelegenci: okrągłe avatary z cienkim ringiem; nazwisko + tytuł POD avatarem
2828
- stopka bez paska:
29-
* lewy dół: skośny blok CG tylko z adresem "pythonlodz.org"
29+
* lewy dół: skośny blok CG z "Meetup #<id>" i "pythonlodz.org" (z ikoną linku)
3030
* środek: lokalizacja (z pinem)
3131
"""
3232

@@ -91,6 +91,7 @@ def generate_featured_image(
9191
"footer_font": preset["footer_font"],
9292
"icon_link": preset["icon_link"],
9393
"icon_pin": preset["icon_pin"],
94+
"link_enabled": aspect_ratio == "16x9",
9495
}
9596
if options:
9697
opt.update(options)
@@ -186,7 +187,7 @@ def generate_featured_image(
186187
# stopka
187188
site_text = getattr(meetup, "website", None) or "pythonlodz.org"
188189
self._draw_corner_footer(
189-
img, draw, site_text, meetup.location_name(language), meetup_id, opt
190+
img, draw, site_text, meetup.location_name(language), opt
190191
)
191192

192193
output_path.parent.mkdir(parents=True, exist_ok=True)
@@ -235,7 +236,7 @@ def _aspect_preset(self, aspect: str) -> dict:
235236
}
236237
if aspect == "1x1":
237238
return {
238-
"safe_margin": 120, # więcej miejsca od góry (nagłówek dalej od wstęgi)
239+
"safe_margin": 90, # więcej miejsca od góry i od dołu
239240
"max_content_width": 980,
240241
"date_block_max_width_ratio": 0.90,
241242
"duo_mode": "stack",
@@ -291,14 +292,13 @@ def _draw_header_centered(
291292
shadow_color=(0, 0, 0, 90),
292293
)
293294

294-
# ---------------- ribbon ----------------
295295
def _draw_top_right_ribbon_en(
296296
self, img: Image.Image, opt: dict, label: str = "ENGLISH EDITION"
297297
):
298298
"""
299299
Ukośna wstęga w prawym górnym rogu:
300-
- kąt zgodny z dolnym trójkątem (stałe nachylenie ~0.406),
301-
- od krawędzi do krawędzi z nadmiarem,
300+
- równoległa do krawędzi trójkąta stopki (atan2(0.26*H, 0.36*W)),
301+
- od krawędzi do krawędzi z nadmiarem (brak szczelin),
302302
- flaga + napis wycentrowane na osi wstęgi.
303303
"""
304304
W, H = img.width, img.height
@@ -308,7 +308,7 @@ def _draw_top_right_ribbon_en(
308308
cos_t, sin_t = math.cos(theta), math.sin(theta)
309309

310310
# odległości punktów końcowych na krawędziach
311-
m = int(0.28 * W) # po górnej krawędzi od prawej
311+
m = int(0.33 * W) # po górnej krawędzi od prawej
312312
n = int(m * math.tan(theta)) # w dół po prawej krawędzi
313313

314314
thickness = 72
@@ -360,7 +360,7 @@ def add(p, dx, dy):
360360
cd = ImageDraw.Draw(content)
361361

362362
flag_img = None
363-
flag_h = min(box_h - 10, 40)
363+
flag_h = min(box_h - 10, 35)
364364
flag_w = flag_h
365365
if self.icon_flag_gb and self.icon_flag_gb.exists():
366366
try:
@@ -377,11 +377,11 @@ def add(p, dx, dy):
377377
gap = 12 if flag_img else 0
378378
total_w = label_w + (flag_w + gap if flag_img else 0)
379379

380-
x0 = max(0, (box_w - total_w) // 2)
380+
x0 = max(0, (box_w - total_w - 2) // 2)
381381
y0 = (box_h - cd.textbbox((0, 0), label, font=font)[3]) // 2
382382

383383
if flag_img:
384-
content.alpha_composite(flag_img, (x0, (box_h - flag_h) // 2))
384+
content.alpha_composite(flag_img, (x0, (box_h - flag_h + 10) // 2))
385385
x0 += flag_w + gap
386386

387387
cd.text((x0, y0 + 2), label, font=font, fill=(255, 255, 255, 90))
@@ -396,55 +396,63 @@ def add(p, dx, dy):
396396
img.alpha_composite(ribbon)
397397
img.alpha_composite(content_rot, (cx, cy))
398398

399-
# ---------------- footer ----------------
400399
def _draw_corner_footer(
401400
self,
402401
img: Image.Image,
403402
draw: ImageDraw.ImageDraw,
404403
site_text: str,
405404
place_text: str,
406-
meetup_id: str | int,
407405
opt: dict,
408406
):
409407
"""
410408
Skośny trójkąt w lewym dolnym rogu + lokalizacja na środku.
411-
- trójkąt zawiera tylko adres strony (bez "Meetup #<id>" i bez ikony linku)
412-
- kąt trójkąta stały, zgodny z wstęgą EN
409+
Kąt trójkąta jest zgodny z 16x9 niezależnie od proporcji.
413410
"""
414411
W, H = img.width, img.height
415412
pad = opt["safe_margin"]
416413

417-
tri_slope = 0.406 # spójny z wstęgą
414+
# bazowa szerokość, wysokość wynikająca ze stałego nachylenia ~0.406
415+
base_block_w = int(W * 0.36 * 0.85)
416+
tri_slope = 0.406 # pochylanie dopasowane do projektu 16x9
417+
base_block_h = int(base_block_w * tri_slope)
418+
418419
font_site = self._load_font(self.font_normal, opt["footer_font"])
419420

420421
site_bbox = draw.textbbox((0, 0), site_text, font=font_site)
422+
421423
site_w, site_h = site_bbox[2], site_bbox[3]
422424

423-
text_margin_x = 74
425+
text_gap = 8
426+
text_margin_x = 54
424427
inner_pad = 30
428+
meet_w = 100
429+
meet_h = 30
430+
req_w = max(meet_w, site_w) + text_margin_x * 2
431+
req_h = meet_h + text_gap + site_h + inner_pad * 2
425432

426-
base_block_w = int(W * 0.36 * 0.85)
427-
req_w = site_w + text_margin_x * 2
428433
block_w = max(base_block_w, req_w)
429-
block_h = int(block_w * tri_slope)
434+
block_h = max(base_block_h, req_h)
430435

431436
poly = [(0, H), (0, H - block_h), (block_w, H)]
432437
draw.polygon(poly, fill=self.CG)
433438

434439
m = block_h / float(block_w) if block_w else 0.0
435-
436-
total_text_h = site_h
440+
total_text_h = meet_h + text_gap + site_h
437441
bottom_anchor_y = H - inner_pad - total_text_h
438442
y_top_inside = (H - block_h) + m * text_margin_x + inner_pad
439443
start_y = int(max(y_top_inside, bottom_anchor_y))
440444
start_x = text_margin_x
441445

442-
draw.text(
443-
(start_x, start_y),
444-
site_text,
445-
fill="#E8EEF5",
446-
font=font_site,
447-
)
446+
# dolna linia: ikona linku + adres
447+
site_y = start_y + text_gap
448+
text_x = start_x
449+
if opt["link_enabled"]:
450+
draw.text(
451+
(text_x, site_y),
452+
site_text,
453+
fill="#E8EEF5",
454+
font=font_site,
455+
)
448456

449457
# środek – lokalizacja (pin + tekst)
450458
small_font = self._load_font(self.font_normal, max(22, opt["footer_font"]))
@@ -501,16 +509,19 @@ def _layout_single(
501509
name_h = draw.textbbox((0, 0), sp.name, font=name_f)[3]
502510
title_h = self._multiline_height(draw, lines, title_f, gap=8)
503511

512+
# overlay pod całą sekcją (avatar + tekst poniżej) z nieco mniejszymi marginesami
504513
overlay_bottom = box_y + size + 32 + name_h + 8 + title_h + 24
505514
self._overlay(
506515
img,
507516
(box_x, box_y, box_x + box_w, overlay_bottom),
508517
opt["overlay_opacity"],
509518
)
510519

520+
# avatar
511521
av_x = img.width // 2 - size // 2
512522
self._paste_with_ring_thin(img, av, (av_x, box_y))
513523

524+
# nazwisko i tytuł POD avatarem
514525
name_y = box_y + size + 24
515526
title_y = name_y + name_h + 8
516527

0 commit comments

Comments
 (0)