Initial commit: organize Primary song slides repo
One folder per song under songs/. Tracks PPTX slide files and Python generation scripts. PDFs and videos excluded (too large for git; originals are in Google Drive). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import fitz
|
||||
from pptx import Presentation
|
||||
from pptx.util import Emu, Inches
|
||||
import io
|
||||
|
||||
PDF_PATH = r"C:\Users\jhodgkin\Pictures\Holy Places Flip Chart.pdf"
|
||||
OUT_PATH = r"C:\Users\jhodgkin\Pictures\Holy Places Flip Chart.pptx"
|
||||
DPI = 150
|
||||
|
||||
SLIDE_W = Inches(13.333) # widescreen landscape
|
||||
SLIDE_H = Inches(7.5)
|
||||
GAP = Inches(0.1)
|
||||
|
||||
doc = fitz.open(PDF_PATH)
|
||||
prs = Presentation()
|
||||
prs.slide_width = SLIDE_W
|
||||
prs.slide_height = SLIDE_H
|
||||
blank_layout = prs.slide_layouts[6]
|
||||
|
||||
def render_page(page):
|
||||
mat = fitz.Matrix(DPI / 72, DPI / 72)
|
||||
pix = page.get_pixmap(matrix=mat, alpha=False)
|
||||
return io.BytesIO(pix.tobytes("png")), pix.width, pix.height
|
||||
|
||||
def add_single_slide(page, label):
|
||||
img, pw, ph = render_page(page)
|
||||
slide = prs.slides.add_slide(blank_layout)
|
||||
aspect = pw / ph
|
||||
h = SLIDE_H
|
||||
w = int(h * aspect)
|
||||
if w > SLIDE_W:
|
||||
w = SLIDE_W
|
||||
h = int(w / aspect)
|
||||
left = (SLIDE_W - w) // 2
|
||||
top = (SLIDE_H - h) // 2
|
||||
slide.shapes.add_picture(img, left, top, width=w, height=h)
|
||||
print(f" Slide: {label}")
|
||||
|
||||
def add_pair_slide(page_a, page_b, label):
|
||||
img_a, pw_a, ph_a = render_page(page_a)
|
||||
img_b, pw_b, ph_b = render_page(page_b)
|
||||
slide = prs.slides.add_slide(blank_layout)
|
||||
|
||||
usable_w = (SLIDE_W - GAP) // 2
|
||||
|
||||
def fit(pw, ph):
|
||||
aspect = pw / ph
|
||||
h = SLIDE_H
|
||||
w = int(h * aspect)
|
||||
if w > usable_w:
|
||||
w = usable_w
|
||||
h = int(w / aspect)
|
||||
return w, h
|
||||
|
||||
wa, ha = fit(pw_a, ph_a)
|
||||
wb, hb = fit(pw_b, ph_b)
|
||||
|
||||
top_a = (SLIDE_H - ha) // 2
|
||||
top_b = (SLIDE_H - hb) // 2
|
||||
|
||||
# Center the pair horizontally
|
||||
total_w = wa + GAP + wb
|
||||
left_a = (SLIDE_W - total_w) // 2
|
||||
left_b = left_a + wa + GAP
|
||||
|
||||
slide.shapes.add_picture(img_a, left_a, top_a, width=wa, height=ha)
|
||||
slide.shapes.add_picture(img_b, left_b, top_b, width=wb, height=hb)
|
||||
print(f" Slide: {label}")
|
||||
|
||||
pages = list(doc)
|
||||
|
||||
# Page 1 alone
|
||||
add_single_slide(pages[0], "page 1")
|
||||
|
||||
# Pages 2+ in pairs
|
||||
for i in range(1, len(pages), 2):
|
||||
if i + 1 < len(pages):
|
||||
add_pair_slide(pages[i], pages[i + 1], f"pages {i+1}+{i+2}")
|
||||
else:
|
||||
add_single_slide(pages[i], f"page {i+1}")
|
||||
|
||||
prs.save(OUT_PATH)
|
||||
print(f"\nSaved: {OUT_PATH}")
|
||||
Reference in New Issue
Block a user