Generate PowerPoint material for "I tried to sing with XX" [python-pptx]

Overview

I wrote the python code to generate the original lyrics, parody lyrics, and the corresponding image in a fixed place as PowerPoint slides, assuming that it will be used as the material for the "I tried to sing with XX" video. スクリーンショット 2020-03-22 18.50.40.png

background

Parody songs sung to reproduce the original lyrics with only nouns of a specific genre are commonly known as the "I tried to sing with XX" series. In the "I tried to sing with XX" video, the original lyrics, parody lyrics, and the following images with the corresponding images placed in a fixed place are often shown in a picture-story show format. When there are many nouns appearing in parody lyrics, it is difficult to manually create the corresponding video material, so I wanted to automate it programmatically. I also thought it would be even more convenient if people could fine-tune what was generated by the program, so I decided to make it as a PowerPoint slide. For this, I used a library called python-pptx that can generate pptx files from python.

environment

macOS Catalina version 10.15.3 python3.8.0 or python3.7.0

What to prepare

Image file

Prepare an image to insert in PowerPoint. This time, I will use the national flag image obtained from this method.

Correspondence table of nouns and image file names

Prepare a csv file in which the noun ID and the corresponding image file name are entered separated by commas as shown below. The noun ID is used in the lyrics definition file described later.

img_file_names.csv


Iceland,Flag_of_Iceland.png
Ireland,Flag_of_Ireland.png
Azerbaijan,Flag_of_Azerbaijan.png
Afghanistan,Flag_of_Afghanistan.png
Abkhazia,Flag_of_the_Republic_of_Abkhazia.png
United States of America,Flag_of_the_United_States.png
United Arab Emirates,Flag_of_the_United_Arab_Emirates.png
Algeria,Flag_of_Algeria.png
...

Lyrics definition file

Prepare the following csv in which the original lyrics, parody lyrics, and the noun ID of the image to be displayed are entered one by one on each line separated by commas. I felt that it was troublesome to write the file name for the noun ID part, so I made a separate table to replace the noun ID with the file name. If you don't mind writing the image file name directly, you don't have to write the correspondence table.

lyric.csv


Subaru in the wind,Kazakhstan Tuvalu,Kazakhstan
Subaru in the wind,Kazakhstan Tuvalu,Tuvalu
Galaxy in the sand,Swaziland Guinea,Swaziland
Galaxy in the sand,Swaziland Guinea,Guinea
Where did everyone go,Indonesia India,Indonesia
Where did everyone go,Indonesia India,India
Without being watched over,Mari Monaco Lesotho Monaco,Republic of Mali
Without being watched over,Mari Monaco Lesotho Monaco,Monaco
Without being watched over,Mari Monaco Lesotho Monaco,Lesotho
Without being watched over,Mari Monaco Lesotho Monaco,Monaco
...

file organization

The folder name for storing image files is pictures, the correspondence table between nomenclature and image file names is img_file_names.csv, and the lyrics definition file is lyric.csv. Also, let's say generate_pptx.py is the python script that generates PowerPoint. Place these files as shown below.

.
├── generate_pptx.py
├── pitcures
│   ├── Flag_of_Afghanistan.png
│   ├── Flag_of_Albania.png
│   └── ...
├── img_file_names.csv
├── lyric.csv

code

In the above file structure, I will explain the python script that outputs the PowerPoint file that is the material of the "I tried to sing with XX" video. I'll put the whole code at the end. By editing this code as a basis, you can add characters and images, change the layout, etc. See also the official python-pptx documentation (https://python-pptx.readthedocs.io/en/latest/index.html) if needed.

Library installation

Since python-pptx and Pillow are used, please install by the following command etc. if necessary.

pip install python-pptx
pip install Pillow

import and setting various constants

Import the library and set various constants. Note that the slide size is in English Metric Unit (EMU; 1 cm = 360,000 emu). (Reference: [I want to change the size of the slide with python-pptx](https://ja.stackoverflow.com/questions/37638/python-pptx%E3%81%A7%E3%82%B9%E3%83%] A9% E3% 82% A4% E3% 83% 89% E3% 81% AE% E3% 82% B5% E3% 82% A4% E3% 82% BA% E3% 82% 92% E5% A4% 89% E3% 81% 88% E3% 81% 9F% E3% 81% 84))

from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from PIL import Image
from pptx.dml.color import RGBColor

#Slide size
#4:3 (default) 9144000x6858000
#16:9 12193200x6858000
SLIDE_WIDTH = 12193200
SLIDE_HEIGHT = 6858000
BACKGROUD_RGB = RGBColor(0,0,0)
FONT_RGB = RGBColor(255,255,255)

OUTPUT_FILE_PATH = "test.pptx"

#The height of the upper left coordinate of the parody lyrics text box(Not required because the left and right directions are centered)
IMG_FILE_PATH = "img_file_names.csv"#A csv file with one id and one image path per line
IMG_DIR = "./picture/"
LYRIC_FILE_PATH = "lyric.csv"#A csv file with the original lyrics, parody lyrics, and image file ID written one by one per line

PARODY_LYRIC_HEIGHT = Inches(5.5)
PARODY_LYRIC_FONTSIZE = Pt(36)

ORIGINAL_LYRIC_HEIGHT = Inches(6.5)
ORIGINAL_LYRIC_FONTSIZE = Pt(28)

IMG_DISPLAY_HEIGHT = Inches(3) #The height of the image when displayed on a slide. For the time being, set it to 3 inches.
 IMG_CENTER_X, IMG_CENTER_Y = SLIDE_WIDTH / 2, SLIDE_HEIGHT / 2 # Image center coordinates `` `

##Get configuration file information Assign the information in the correspondence table to the variable name2path (dict type) and the information in the lyrics definition file to the variable called lyrics (list type).

name2path = {}
with open(IMG_FILE_PATH,"r") as f:
    text = [v.split(',') for v in f.read().split("\n")]
    for v in text:
        if len(v) == 2:
            name2path[v[0]]=IMG_DIR+v[1]
lyrics=[]
with open(LYRIC_FILE_PATH,"r") as f:
    lyrics = [v.split(',') for v in f.read().split("\n") if len(v.split(','))==3]

##Generate and size presentation objects Slide size is Presentation.slide_width、Presentation.slide_It can be changed by assigning a value to height.

# Definition of slide object
prs = Presentation()
# Specify slide size
prs.slide_width = SLIDE_WIDTH
prs.slide_height = SLIDE_HEIGHT

##Add slides corresponding to each element of lyrics in the for statement From here, I will explain the process of adding slides corresponding to each element of lyrics with a for statement. First, the 0th, 1st, and 2nd elements of lyrics are the original lyrics (original)._text), parody lyrics (parody)_text), image ID (img_Since it corresponds to id), get it. If the image ID does not exist in the correspondence table, continue. File path (img) if it exists_file) is acquired.

for index,lyric in enumerate(lyrics):
    original_text = lyric[0]
    parody_text = lyric[1]
    img_id = lyric[2]
    if img_id not in name2path:
        print("img_id",img_id,"does not exist") 
        print("line",index,":",lyric,"is ignored") 
        continue 
    img_file = name2path[img_id] 

##Add a blank slide Add a blank slide to the Presentation object_slide

 #Add blank slides
    blank_slide_layout = prs.slide_layouts[6]    
    slide = prs.slides.add_slide(blank_slide_layout) 

##Blacken the background of the slide

 #Black background
    shapes = slide.shapes
    left, top, width, height = 0, 0, SLIDE_WIDTH, SLIDE_HEIGHT
    shape = shapes.add_textbox(left,top,width,height)
    fill = shape.fill
    fill.solid()
    fill.fore_color.rgb = BACKGROUD_RGB

Add a textBox that is the same size as the slide and fill it in black. ##Insert image Image IMG_CENTER_X, IMG_CENTER_Insert it in a position centered on Y. Originally, python-add by pptx_In the picture, only the upper left coordinate position can be specified, but in the "I tried singing with XX" video, it is better to have the image center aligned before and after the picture is switched, so after acquiring the image size separately, insert it by centering. To do. The detailed method ispython-Center the image with pptxPlease refer to it as it is summarized in.

 #Get image size and get aspect ratio
    im = Image.open(img_file)
    im_width, im_height = im.size
    aspect_ratio = im_width/im_height

 #Calculate the size of the displayed image
    img_display_height = IMG_DISPLAY_HEIGHT
    img_display_width = aspect_ratio*img_display_height

 #Calculate the upper left coordinates of the image when centering
    left = IMG_CENTER_X - img_display_width / 2
    top = IMG_CENTER_Y - img_display_height / 2

 #Add image to slide
    slide.shapes.add_picture(img_file, left, top, height = IMG_DISPLAY_HEIGHT)

##Insert parody lyrics Add parody lyrics. Specify the width of the text box to be the same as the slide width, and then PP_ALIGN.By centering in the left-right direction with CENTER, the lyrics will be displayed in the center. Font color and font size are fonts.size、font.color.Specify by assigning a value to rgb.

 #Add text box
    left, top, width, height = 0, PARODY_LYRIC_HEIGHT, SLIDE_WIDTH, Inches(1) 
    txBox = slide.shapes.add_textbox(left, top, width, height) 
    tf = txBox.text_frame 
    tf.text = parody_text
    paragraph = tf.paragraphs[0]
    font = paragraph.font 
    font.size = PARODY_LYRIC_FONTSIZE
    font.color.rgb = FONT_RGB 
 paragraph.alignment = PP_ALIGN.CENTER #Left and right centering

##Insert the original lyrics Insert the original lyrics. The method is the same as inserting parody lyrics.

 #Add text box
    left, top, width, height = 0, ORIGINAL_LYRIC_HEIGHT, SLIDE_WIDTH, Inches(1) 
    txBox = slide.shapes.add_textbox(left, top, width, height) 
    tf = txBox.text_frame 
    tf.text = original_text
    paragraph = tf.paragraphs[0]
    font = paragraph.font 
    font.size = ORIGINAL_LYRIC_FONTSIZE 
    font.color.rgb = FONT_RGB
    paragraph.alignment = PP_ALIGN.CENTER 

##output After finishing the for statement, Presentation.Output the pptx file with save.

prs.save(OUTPUT_FILE_PATH)

#Whole code The entire code is below.

generate_pptx.py



from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from PIL import Image
from pptx.dml.color import RGBColor

# Slide size
4:3 (default) 9144000x6858000
16:9 12193200x6858000
SLIDE_WIDTH = 12193200
SLIDE_HEIGHT = 6858000
BACKGROUD_RGB = RGBColor(0,0,0)
FONT_RGB = RGBColor(255,255,255)

OUTPUT_FILE_PATH = "test.pptx"

# The height of the upper left coordinate of the parody lyrics text box (not necessary because the left and right directions are centered)
 IMG_FILE_PATH = "img_file_names.csv" # csv file with one id and one image path per line
IMG_DIR = "./picture/"
 LYRIC_FILE_PATH = "lyric.csv" # A csv file in which the original lyrics, parody lyrics, and image file ID are written one by one per line.

PARODY_LYRIC_HEIGHT = Inches(5.5)
PARODY_LYRIC_FONTSIZE = Pt(36)

ORIGINAL_LYRIC_HEIGHT = Inches(6.5)
ORIGINAL_LYRIC_FONTSIZE = Pt(28)

 IMG_DISPLAY_HEIGHT = Inches (3) #The height of the image when displayed on a slide. For the time being, set it to 3 inches.
 IMG_CENTER_X, IMG_CENTER_Y = SLIDE_WIDTH / 2, SLIDE_HEIGHT / 2 #Center coordinates of the image

name2path = {}
with open(IMG_FILE_PATH,"r") as f:
    text = [v.split(',') for v in f.read().split("\n")]
    for v in text:
        if len(v) == 2:
            name2path[v[0]]=IMG_DIR+v[1]
lyrics=[]
with open(LYRIC_FILE_PATH,"r") as f:
    lyrics = [v.split(',') for v in f.read().split("\n") if len(v.split(','))==3]

# Definition of slide object
prs = Presentation()
# Specify slide size
prs.slide_width = SLIDE_WIDTH
prs.slide_height = SLIDE_HEIGHT

for index,lyric in enumerate(lyrics):
    original_text = lyric[0]
    parody_text = lyric[1]
    img_id = lyric[2]
    if img_id not in name2path:
        print("img_id",img_id,"does not exist") 
        print("line",index,":",lyric,"is ignored") 
        continue 
    img_file = name2path[img_id] 

 #Add blank slides
    blank_slide_layout = prs.slide_layouts[6]    
    slide = prs.slides.add_slide(blank_slide_layout) 
    
 #Black background
    shapes = slide.shapes
    left, top, width, height = 0, 0, SLIDE_WIDTH, SLIDE_HEIGHT
    shape = shapes.add_textbox(left,top,width,height)
    fill = shape.fill
    fill.solid()
    fill.fore_color.rgb = BACKGROUD_RGB
    
 #Get image size and get aspect ratio
    im = Image.open(img_file)
    im_width, im_height = im.size
    aspect_ratio = im_width/im_height
    
 #Calculate the size of the displayed image
    img_display_height = IMG_DISPLAY_HEIGHT
    img_display_width = aspect_ratio*img_display_height
    
 #Calculate the upper left coordinates of the image when centering
    left = IMG_CENTER_X - img_display_width / 2
    top = IMG_CENTER_Y - img_display_height / 2
    
 #Add image to slide
    slide.shapes.add_picture(img_file, left, top, height = IMG_DISPLAY_HEIGHT)
      
 #Add text box
    left, top, width, height = 0, PARODY_LYRIC_HEIGHT, SLIDE_WIDTH, Inches(1) 
    txBox = slide.shapes.add_textbox(left, top, width, height) 
    tf = txBox.text_frame 
    tf.text = parody_text
    paragraph = tf.paragraphs[0]
    font = paragraph.font 
    font.size = PARODY_LYRIC_FONTSIZE
    font.color.rgb = FONT_RGB 
    paragraph.alignment = PP_ALIGN.CENTER 
    
 #Add text box
    left, top, width, height = 0, ORIGINAL_LYRIC_HEIGHT, SLIDE_WIDTH, Inches(1) 
    txBox = slide.shapes.add_textbox(left, top, width, height) 
    tf = txBox.text_frame 
    tf.text = original_text
    paragraph = tf.paragraphs[0]
    font = paragraph.font 
    font.size = ORIGINAL_LYRIC_FONTSIZE 
    font.color.rgb = FONT_RGB
    paragraph.alignment = PP_ALIGN.CENTER 

prs.save(OUTPUT_FILE_PATH)

#in conclusion When the pptx file is output, you can use it as a material for video editing software by making fine adjustments and exporting it to png etc. with the export function. The above code will create a simple slide, but try changing the lyrics, image insertion position, text color and background color to your liking.

Recommended Posts

Generate PowerPoint material for "I tried to sing with XX" [python-pptx]
I tried to generate ObjectId (primary key) with pymongo
I tried to automatically generate a password with Python3
[Pandas] I tried to analyze sales data with Python [For beginners]
I tried to make a strange quote for Jojo with LSTM
I tried to implement Autoencoder with TensorFlow
I tried to visualize AutoEncoder with TensorFlow
I tried to get started with Hy
I tried to implement CVAE with PyTorch
I tried to solve TSP with QAOA
I tried to refer to the fun rock-paper-scissors poi for beginners with Python
I tried to detect Mario with pytorch + yolov3
I tried to implement reading Dataset with PyTorch
I tried to use lightGBM, xgboost with Boruta
I tried to learn logical operations with TF Learn
I tried to move GAN (mnist) with keras
I implemented DCGAN and tried to generate apples
I tried to save the data with discord
I tried to detect motion quickly with OpenCV
I tried to integrate with Keras in TFv1.1
I tried to get CloudWatch data with Python
I tried to output LLVM IR with Python
I tried to make AI for Smash Bros.
I tried to detect an object with M2Det!
I tried to automate sushi making with python
I tried to predict Titanic survival with PyCaret
I tried to generate a random character string
I tried to operate Linux with Discord Bot
I tried to study DP with Fibonacci sequence
I tried to start Jupyter with Amazon lightsail
I tried to judge Tsundere with Naive Bayes
I tried to create a button for Slack with Raspberry Pi + Tact Switch
I tried to learn the sin function with chainer
I tried to move machine learning (ObjectDetection) with TouchDesigner
I tried to create a table only with Django
I tried to extract features with SIFT of OpenCV
I tried to move Faster R-CNN quickly with pytorch
I tried to read and save automatically with VOICEROID2 2
I tried to implement and learn DCGAN with PyTorch
I tried to get started with blender python script_Part 01
I tried to touch the CSV file with Python
I tried to draw a route map with Python
[For beginners in competition professionals] I tried to solve 40 AOJ "ITP I" questions with python
I tried to automatically read and save with VOICEROID2
I tried to get started with blender python script_Part 02
I tried to automatically generate a character string to be input to Mr. Adjustment with Python
I tried to implement an artificial perceptron with python
I tried to build ML Pipeline with Cloud Composer
I tried to implement time series prediction with GBDT
I tried to create a reinforcement learning environment for Othello with Open AI gym
[Introduction to Pytorch] I tried categorizing Cifar10 with VGG16 ♬
[Python-pptx] Output PowerPoint font information to csv with python
I tried to solve the problem with Python Vol.1
I tried to analyze J League data with Python
I tried a simple RPA for login with selenium
I tried to implement Grad-CAM with keras and tensorflow
I tried to make an OCR application with PySimpleGUI
I tried to implement SSD with PyTorch now (Dataset)
I tried to interpolate Mask R-CNN with Optical Flow
I tried to step through Bayesian optimization. (With examples)
I tried to find an alternating series with tensorflow