Spaces:
Running
on
Zero
Running
on
Zero
| from pptx import Presentation | |
| from pptx.util import Inches | |
| from pptx.oxml.xmlchemy import OxmlElement | |
| from pptx.dml.color import RGBColor | |
| from pptx.enum.text import PP_ALIGN, MSO_ANCHOR, MSO_AUTO_SIZE | |
| import random | |
| import os | |
| from PIL import Image | |
| from typing import List, Callable | |
| from .llm_utils import llm_generate_titles, llm_generate_text, llm_generate_image_prompt, llm_generate_background_prompt | |
| from .prompt_configs import PromptConfig | |
| from .slides import generate_slide | |
| from .kandinsky import generate_image | |
| from .font import Font | |
| import tqdm | |
| def generate_presentation( | |
| llm_generate: Callable[[str], str], | |
| generate_image: Callable[[str, int, int], Image.Image], | |
| prompt_config: PromptConfig, | |
| description: str, | |
| font:Font, | |
| output_dir: str, | |
| ) -> Presentation: | |
| """ | |
| Generate a PowerPoint presentation based on a description using language and image models. | |
| Args: | |
| llm_generate (Callable[[str], str]): Function to generate text using a language model. | |
| generate_image (Callable[[str, int, int], Image.Image]): Function to generate images. | |
| prompt_config (PromptConfig): Configuration for prompts. | |
| description (str): Description of the presentation. | |
| output_dir (str): Directory to save generated images and presentation. | |
| font (Font): Font object to manage font styles and paths. | |
| Returns: | |
| Presentation: The generated PowerPoint presentation. | |
| """ | |
| os.makedirs(os.path.join(output_dir, 'backgrounds'), exist_ok=True) | |
| os.makedirs(os.path.join(output_dir, 'pictures'), exist_ok=True) | |
| presentation = Presentation() | |
| presentation.slide_height = Inches(9) | |
| presentation.slide_width = Inches(16) | |
| pbar = tqdm.tqdm(total=4, desc="Presentation goes brrr...") | |
| pbar.set_description("Generating titles for presentation") | |
| titles = llm_generate_titles(llm_generate, description, prompt_config) | |
| pbar.update(1) | |
| pbar.set_description("Generating text for slides") | |
| texts = [None] + llm_generate_text( | |
| llm_generate, | |
| description, | |
| titles, | |
| prompt_config | |
| ) | |
| pbar.update(1) | |
| # postfix added to keywords describing presentation | |
| background_style = random.choice(prompt_config.background_styles) | |
| picture_paths = [] | |
| background_paths = [] | |
| pbar.set_description("Generating images for slides") | |
| for t_index, (title, text) in enumerate(zip(titles, texts)): | |
| # Decide randomly presence of image on current slide | |
| if random.choices( | |
| [True, False], | |
| # side-image/plain-text with background image | |
| weights=[4, 1], | |
| k=1)[0] and text: | |
| image_width, image_height = random.choice( | |
| [(768, 1344), (1024, 1024)] | |
| ) | |
| caption_prompt = llm_generate_image_prompt( | |
| llm_generate, | |
| description, | |
| title, | |
| prompt_config | |
| ) | |
| picture = generate_image( | |
| prompt=caption_prompt, | |
| width=image_width, | |
| height=image_height | |
| ) | |
| picture_path = os.path.join( | |
| output_dir, | |
| 'pictures', | |
| f'{t_index:06}.png' | |
| ) | |
| picture.save(picture_path) | |
| else: | |
| picture_path = None | |
| picture_paths.append(picture_path) | |
| if picture_path is None: | |
| background_width, background_height = 1344, 768 | |
| background_prompt = llm_generate_background_prompt( | |
| llm_generate, | |
| description, | |
| title, | |
| prompt_config, | |
| background_style | |
| ) | |
| background = generate_image( | |
| prompt=background_prompt, | |
| width=background_width, | |
| height=background_height | |
| ) | |
| background_path = os.path.join( | |
| output_dir, | |
| 'backgrounds', | |
| f'{t_index:06}.png' | |
| ) | |
| background.save(background_path) | |
| else: | |
| background_path = None | |
| background_paths.append(background_path) | |
| pbar.update(1) | |
| pbar.set_description("Packing presentation") | |
| for index in range(len(titles)): | |
| title = titles[index] | |
| text = texts[index] | |
| picture_path = picture_paths[index] | |
| background_path = background_paths[index] | |
| generate_slide( | |
| presentation=presentation, | |
| title=title, | |
| text=text, | |
| picture_path=picture_path, | |
| background_path=background_path, | |
| font=font, | |
| ) | |
| pbar.update(1) | |
| pbar.set_description("Done") | |
| output_path = os.path.join(output_dir, 'presentation.pptx') | |
| presentation.save(output_path) | |
| return presentation |