Spaces:
Runtime error
Runtime error
| 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 | |
| from typing import List, Callable, Optional | |
| from PIL import Image | |
| import random | |
| import tqdm | |
| import os | |
| from src.font import Font | |
| from .slide_utils import add_paragraph | |
| def generate_text_title_image_right( | |
| presentation: Presentation, | |
| title: str, | |
| text: str, | |
| picture_path: str, | |
| font:Font, | |
| text_font_coeff:float=0.6, | |
| ) -> None: | |
| """ | |
| Add a slide with title, text on the left, and picture on the right. | |
| Args: | |
| presentation (Presentation): PowerPoint presentation object | |
| title (str): Title for the slide | |
| text (str): Text content for the left side of the slide | |
| picture_path (str): Path to the picture to be inserted on the right side | |
| font (Font): Font object to manage font styles and paths. | |
| text_font_coeff (float): Coefficient to adjust the font size of the text relative to the title (default is 0.6). | |
| Returns: | |
| None | |
| """ | |
| slide_layout = presentation.slide_layouts[6] | |
| slide = presentation.slides.add_slide(slide_layout) | |
| slide_height = 9 | |
| slide_width = 16 | |
| margin = min(slide_height, slide_width) / 18 | |
| # image params | |
| # original image size | |
| x_pixels, y_pixels = Image.open(picture_path).size | |
| assert x_pixels == y_pixels or x_pixels < y_pixels, \ | |
| 'only vertical and square images can be used' | |
| # we need image height to be equal to slide height | |
| image_height = slide_height | |
| # x_pixels / y_pixels = image_width / image_height | |
| image_width = x_pixels / y_pixels * image_height | |
| image_left = slide_width - image_width | |
| image_top = 0 | |
| slide.shapes.add_picture( | |
| picture_path, | |
| left=Inches(image_left), | |
| top=Inches(image_top), | |
| width=Inches(image_width), | |
| height=Inches(image_height), | |
| ) | |
| # title params | |
| title_left = margin | |
| title_top = margin | |
| title_width = slide_width - image_width - 2*margin | |
| title_height = slide_height / 6 | |
| title_box = slide.shapes.add_textbox( | |
| left=Inches(title_left), | |
| top=Inches(title_top), | |
| width=Inches(title_width), | |
| height=Inches(title_height), | |
| ) | |
| title_frame = title_box.text_frame | |
| title_frame.clear() | |
| title_frame.vertical_anchor = MSO_ANCHOR.MIDDLE | |
| title_frame.auto_size = MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE | |
| title_frame.word_wrap = False | |
| # title_paragraph = title_frame.add_paragraph() | |
| title_paragraph = add_paragraph(title_frame) | |
| title_paragraph.alignment = PP_ALIGN.CENTER | |
| title_paragraph.text = title | |
| for max_size in range(font.max_size)[::-5]: | |
| try: | |
| title_frame.fit_text( | |
| font_file=font.bold, | |
| max_size=max_size, | |
| bold=True, | |
| ) | |
| break | |
| except: | |
| pass | |
| # text params | |
| title_left = margin | |
| text_top = title_height + margin*2 | |
| text_width = slide_width - image_width - 2*margin | |
| text_height = slide_height - title_height - 3*margin | |
| text_box = slide.shapes.add_textbox( | |
| left=Inches(title_left), | |
| top=Inches(text_top), | |
| width=Inches(text_width), | |
| height=Inches(text_height), | |
| ) | |
| text_frame = text_box.text_frame | |
| text_frame.clear() | |
| text_frame.vertical_anchor = MSO_ANCHOR.MIDDLE | |
| text_frame.auto_size = MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE | |
| text_frame.word_wrap = False | |
| # text_paragraph = text_frame.add_paragraph() | |
| text_paragraph = add_paragraph(text_frame) | |
| text_paragraph.text = text | |
| text_paragraph.alignment = PP_ALIGN.CENTER | |
| for max_size in range(int(max_size*text_font_coeff))[::-5]: | |
| try: | |
| text_frame.fit_text(font_file=font.basic, max_size=max_size) | |
| break | |
| except: | |
| pass | |
| def generate_text_title_image_left( | |
| presentation: Presentation, | |
| title: str, | |
| text: str, | |
| picture_path: str, | |
| font:Font, | |
| text_font_coeff:float=0.6, | |
| ) -> None: | |
| """ | |
| Add a slide with title, text on the left, and picture on the right. | |
| Args: | |
| presentation (Presentation): PowerPoint presentation object | |
| title (str): Title for the slide | |
| text (str): Text content for the left side of the slide | |
| picture_path (str): Path to the picture to be inserted on the right side | |
| font (Font): Font object to manage font styles and paths. | |
| text_font_coeff (float): Coefficient to adjust the font | |
| size of the text relative to the title (default is 0.6). | |
| Returns: | |
| None | |
| """ | |
| slide_layout = presentation.slide_layouts[6] | |
| slide = presentation.slides.add_slide(slide_layout) | |
| slide_height = 9 | |
| slide_width = 16 | |
| margin = min(slide_height, slide_width) / 18 | |
| # image params | |
| # original image size | |
| x_pixels, y_pixels = Image.open(picture_path).size | |
| assert x_pixels == y_pixels or x_pixels < y_pixels, \ | |
| 'only vertical and square images can be used' | |
| # we need image height to be equal to slide height | |
| image_height = slide_height | |
| # x_pixels / y_pixels = image_width / image_height | |
| image_width = x_pixels / y_pixels * image_height | |
| image_left = 0 | |
| image_top = 0 | |
| slide.shapes.add_picture( | |
| picture_path, | |
| left=Inches(image_left), | |
| top=Inches(image_top), | |
| width=Inches(image_width), | |
| height=Inches(image_height), | |
| ) | |
| # title params | |
| title_left = image_width + margin | |
| title_top = margin | |
| title_width = slide_width - image_width - 2 * margin | |
| title_height = slide_height / 6 | |
| title_box = slide.shapes.add_textbox( | |
| left=Inches(title_left), | |
| top=Inches(title_top), | |
| width=Inches(title_width), | |
| height=Inches(title_height), | |
| ) | |
| title_frame = title_box.text_frame | |
| title_frame.clear() | |
| title_frame.vertical_anchor = MSO_ANCHOR.MIDDLE | |
| title_frame.auto_size = MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE | |
| title_frame.word_wrap = False | |
| # title_paragraph = title_frame.add_paragraph() | |
| title_paragraph = add_paragraph(title_frame) | |
| title_paragraph.text = title | |
| title_paragraph.alignment = PP_ALIGN.CENTER | |
| for max_size in range(font.max_size)[::-5]: | |
| try: | |
| title_frame.fit_text( | |
| font_file=font.bold, | |
| max_size=max_size, | |
| bold=True, | |
| ) | |
| break | |
| except: | |
| pass | |
| # text params | |
| text_left = title_left | |
| text_top = title_height + margin * 2 | |
| text_width = slide_width - image_width - 2 * margin | |
| text_height = slide_height - title_height - 3 * margin | |
| text_box = slide.shapes.add_textbox( | |
| left=Inches(text_left), | |
| top=Inches(text_top), | |
| width=Inches(text_width), | |
| height=Inches(text_height), | |
| ) | |
| text_frame = text_box.text_frame | |
| text_frame.vertical_anchor = MSO_ANCHOR.MIDDLE | |
| text_frame.auto_size = MSO_AUTO_SIZE.TEXT_TO_FIT_SHAPE | |
| text_frame.word_wrap = False | |
| # text_paragraph = text_frame.add_paragraph() | |
| text_paragraph = add_paragraph(text_frame) | |
| text_paragraph.text = text | |
| text_paragraph.alignment = PP_ALIGN.CENTER | |
| for max_size in range(int(max_size*text_font_coeff))[::-5]: | |
| try: | |
| text_frame.fit_text( | |
| font_file=font.basic, | |
| max_size=max_size | |
| ) | |
| break | |
| except: | |
| pass | |
| def generate_image_slide( | |
| presentation: Presentation, | |
| title: str, | |
| text: str, | |
| picture_path: str, | |
| font: Font, | |
| text_font_coeff: float = 0.6, | |
| ) -> None: | |
| """ | |
| Generate a slide with a title, text, and an image, choosing the layout randomly. | |
| This function creates a slide in a PowerPoint presentation that includes a title, | |
| text, and an image. The layout is chosen randomly between two options: | |
| image on the right or image on the left. | |
| Args: | |
| presentation (Presentation): PowerPoint presentation object. | |
| title (str): Title for the slide. | |
| text (str): Text content for the slide. | |
| picture_path (str): Path to the picture to be inserted in the slide. | |
| font (Font): Font object to manage font styles and paths. | |
| text_font_coeff (float, optional): Coefficient to adjust the font size of the text | |
| relative to the title (default is 0.65). | |
| Returns: | |
| None | |
| """ | |
| gen_func = random.choice([ | |
| generate_text_title_image_right, | |
| generate_text_title_image_left, | |
| ]) | |
| gen_func( | |
| presentation=presentation, | |
| title=title, | |
| text=text, | |
| picture_path=picture_path, | |
| font=font, | |
| text_font_coeff=text_font_coeff, | |
| ) |