It looks like this ↓
Assuming use on Windows, call and execute the .py
file from the following powershell cmdlet. The cmdlet name is rather long, but there should be no problem because the completion works.
There is also a more direct way for working with Office products while it's running, but since powershell 6 [System.Runtime.InteropServices.Marshal]: : GetActiveObject ()
is no longer available, so pywin32 is used instead.
function Add-Image2ActivePptSlideWithPython {
<#
.SYNOPSIS
Use pywin32 to continuously insert images into currently open PowerPoint slides
#>
if ((Get-Process | Where-Object ProcessName -EQ "POWERPNT").Count -lt 1) {
return
}
$targetPath = @($input).Fullname
if (-not $targetPath) {
return
}
if ((Read-Host "Is the "Do not compress images in files" setting turned on?(y/n)") -ne "y") {
return
}
$tmp = New-TemporaryFile
$targetPath | Out-File -Encoding utf8 -FilePath $tmp.FullName #With BOM
#Place the python script described below in the same directory as this script.
$pyCodePath = "{0}\activeppt_insert-image.py" -f $PSScriptRoot
'python -B "{0}" "{1}"' -f $pyCodePath, $tmp.FullName | Invoke-Expression
Remove-Item -Path $tmp.FullName
}
At the beginning, [Disable image compression](https://support.office.com/ja-jp/article/%E7%94%BB%E5%83%8F%E3%81%AE%E5% 9C% A7% E7% B8% AE% E3% 82% 92% E7% 84% A1% E5% 8A% B9% E3% 81% AB% E3% 81% 99% E3% 82% 8B-81a6b603-0266- 4451-b08e-fc1bf58da658) I'm checking if it's done (because if you forget this, the resolution of the inserted image will drop).
On the actual command line, pass the image object you want to insert via the pipeline as shown below.
ls -File | Add-Image2ActivePptSlideWithPython
There is also a way to pass the path of the image passed via the pipeline as an argument, but in that case it is troublesome to escape special characters and the upper limit of the argument, so I write it to a temporary file created with New-TemporaryFile
.
At this time, even if ʻUTF8` is specified according to the powershell specifications, BOM will be attached, so be careful about the character code.
The called python file should look like this: If you run PowerPoint with PowerPoint running, ʻActivePresentation` will catch the running process. I've made sure the caller has PowerPoint running in advance, but I'm trying to do nothing if the presentation isn't open. Also, if you catch an invisible zombie process, it will terminate the process itself.
activeppt_insert-image.py
"""
Use pywin32 to insert a series of images into the currently open PowerPoint slide
"""
import win32com.client
import argparse
class vb:
msoFalse = 0
msoTrue = -1
ppLayoutBlank = 12
def main(file_list_path):
pptApp = win32com.client.Dispatch("PowerPoint.Application")
if pptApp.Presentations.Count < 1:
if not pptApp.Visible:
pptApp.Quit()
return
with open(file_list_path, "r", encoding="utf_8_sig") as f:
all_lines = f.read()
image_path_list = all_lines.splitlines()
presen = pptApp.ActivePresentation
slide_width = presen.PageSetup.SlideWidth
slide_height = presen.PageSetup.SlideHeight
for img_path in image_path_list:
slide_index = presen.Slides.Count + 1
presen.Slides.Add(slide_index, vb.ppLayoutBlank)
last_slide = presen.Slides(slide_index)
inserted_img = last_slide.Shapes.AddPicture(
FileName = img_path,
LinkToFile = vb.msoFalse,
SaveWithDocument = vb.msoTrue,
Left = 0,
Top = 0
)
inserted_img.Left = (slide_width - inserted_img.Width) / 2
inserted_img.Top = (slide_height - inserted_img.Height) / 2
print(f"inserted: {img_path}")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("file_list_path")
args = parser.parse_args()
main(args.file_list_path)
(´-\ ) .. oO (
GetActiveObject ()` will be implemented soon ...)