| from pptx import Presentation | |
| from pptx.util import Inches, Pt, Emu | |
| from pptx.dml.color import RGBColor | |
| from pptx.enum.text import PP_ALIGN | |
| from pptx.oxml.ns import qn | |
| from lxml import etree | |
| import os | |
| import glob | |
| BASE = '/home/xinyuy/flexvideo/LTX-2/temp_test_suite_gif' | |
| OUT = '/home/xinyuy/flexvideo/LTX-2/results_presentation.pptx' | |
| GIF_W, GIF_H = 640, 142 | |
| CATEGORIES = [ | |
| ('subject_spatial', 'Subject + Spatial Control'), | |
| ('style_spatial', 'Style + Spatial Control'), | |
| ('inpainting_spatial', 'Inpainting + Spatial Control'), | |
| ('inpainting_subject', 'Inpainting + Subject'), | |
| ('multi_spatial', 'Multi Spatial Control'), | |
| ] | |
| ACCENT = RGBColor(0x27, 0x5a, 0xf5) # clean blue | |
| DARK = RGBColor(0x1e, 0x1e, 0x1e) # near-black | |
| GRAY = RGBColor(0x66, 0x66, 0x66) # caption gray | |
| BORDER = RGBColor(0xd0, 0xd8, 0xe8) # light blue-gray border | |
| prs = Presentation() | |
| prs.slide_width = Inches(13.33) | |
| prs.slide_height = Inches(7.5) | |
| blank = prs.slide_layouts[6] | |
| def add_textbox(slide, text, x, y, w, h, size, bold=False, color=DARK, align=PP_ALIGN.LEFT, italic=False): | |
| tb = slide.shapes.add_textbox(x, y, w, h) | |
| tf = tb.text_frame | |
| tf.word_wrap = False | |
| p = tf.paragraphs[0] | |
| p.alignment = align | |
| run = p.add_run() | |
| run.text = text | |
| run.font.size = Pt(size) | |
| run.font.bold = bold | |
| run.font.italic = italic | |
| run.font.color.rgb = color | |
| def add_accent_bar(slide, x, y, w, h, color): | |
| shape = slide.shapes.add_shape(1, x, y, w, h) | |
| shape.fill.solid() | |
| shape.fill.fore_color.rgb = color | |
| shape.line.fill.background() | |
| # ── Title slide ───────────────────────────────────────────────────────────── | |
| slide = prs.slides.add_slide(blank) | |
| # left accent stripe | |
| add_accent_bar(slide, Inches(0), Inches(0), Inches(0.18), prs.slide_height, ACCENT) | |
| add_textbox(slide, 'Video Generation Results', | |
| Inches(0.5), Inches(2.6), Inches(12), Inches(1.1), | |
| size=40, bold=True, color=DARK) | |
| add_textbox(slide, 'Composited control · Subject · Style · Spatial · Inpainting', | |
| Inches(0.5), Inches(3.75), Inches(12), Inches(0.55), | |
| size=16, color=GRAY) | |
| # category chips row | |
| x_chip = Inches(0.5) | |
| for _, name in CATEGORIES: | |
| chip = slide.shapes.add_shape(1, x_chip, Inches(5.0), Inches(2.3), Inches(0.38)) | |
| chip.fill.solid() | |
| chip.fill.fore_color.rgb = RGBColor(0xe8, 0xed, 0xff) | |
| chip.line.color.rgb = ACCENT | |
| tb = chip.text_frame | |
| p = tb.paragraphs[0] | |
| p.alignment = PP_ALIGN.CENTER | |
| run = p.add_run() | |
| run.text = name | |
| run.font.size = Pt(10) | |
| run.font.color.rgb = ACCENT | |
| x_chip += Inches(2.4) | |
| # ── Category slides ────────────────────────────────────────────────────────── | |
| for cat_dir, cat_name in CATEGORIES: | |
| gif_files = sorted(glob.glob(os.path.join(BASE, cat_dir, '*.gif'))) | |
| if not gif_files: | |
| continue | |
| slide = prs.slides.add_slide(blank) | |
| # header band | |
| add_accent_bar(slide, Inches(0), Inches(0), prs.slide_width, Inches(0.72), RGBColor(0xf0, 0xf4, 0xff)) | |
| add_accent_bar(slide, Inches(0), Inches(0.72), prs.slide_width, Inches(0.04), ACCENT) | |
| add_textbox(slide, cat_name, | |
| Inches(0.35), Inches(0.08), Inches(12), Inches(0.6), | |
| size=22, bold=True, color=DARK) | |
| n = len(gif_files) | |
| ncols = 4 if n > 6 else (3 if n > 3 else 2) | |
| MARGIN_X = Inches(0.35) | |
| MARGIN_Y = Inches(0.9) | |
| GAP_X = Inches(0.15) | |
| GAP_Y = Inches(0.08) | |
| LABEL_H = Inches(0.24) | |
| avail_w = prs.slide_width - 2 * MARGIN_X | |
| cell_w = (avail_w - GAP_X * (ncols - 1)) / ncols | |
| img_h = cell_w * GIF_H / GIF_W | |
| row_h = img_h + LABEL_H + GAP_Y + Inches(0.06) | |
| for i, gif_path in enumerate(gif_files): | |
| row = i // ncols | |
| col = i % ncols | |
| x = MARGIN_X + col * (cell_w + GAP_X) | |
| y = MARGIN_Y + row * row_h | |
| # border rect behind image | |
| border = slide.shapes.add_shape(1, x - Inches(0.02), y - Inches(0.02), | |
| cell_w + Inches(0.04), img_h + Inches(0.04)) | |
| border.fill.solid() | |
| border.fill.fore_color.rgb = RGBColor(0xff, 0xff, 0xff) | |
| border.line.color.rgb = BORDER | |
| border.line.width = Emu(9525) # 0.75 pt | |
| pic = slide.shapes.add_picture(gif_path, x, y, cell_w, img_h) | |
| label = os.path.basename(gif_path).replace('.gif', '').replace('_', ' ') | |
| add_textbox(slide, label, | |
| x, y + img_h + Inches(0.04), cell_w, LABEL_H, | |
| size=8, color=GRAY, align=PP_ALIGN.CENTER, italic=True) | |
| prs.save(OUT) | |
| print(f'Saved: {OUT}') | |
Xet Storage Details
- Size:
- 4.85 kB
- Xet hash:
- 67cad9b8217bf0f323346dd23d192d6103d40e4f27552b98cbd0a81327025e51
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.