I am running Python 3.12.10 on Visual Studio Code.
I am working on a python script that opens a PPT file, takes screenshots of each slide and stores them in a temporary directory file under "C:/Users/me/AppData/Temp/", the image files are then opened up using PILLOW library and are appended to an image list in the python script. The end goal is to feed this image list to an LLM that generates a summary of each slide.
Below is a code snippet of the slide extraction using pywin32:
def extract_images_from_ppt_win32(self, ppt_path: str) -> List[Image.Image]:
if not PYWIN32_AVAILABLE:
raise Exception("pywin32 is not available. Install with: pip install pywin32")
images = []
powerpoint = None
presentation = None
try:
print("Using PowerPoint automation to extract slides...")
print("This method bypasses encryption and format issues.")
# Initialize COM
pythoncom.CoInitialize()
# Start PowerPoint application
powerpoint = win32com.client.Dispatch("PowerPoint.Application")
powerpoint.Visible = True # Run in background
# Open the presentation
print(f"Opening presentation: {ppt_path}")
presentation = powerpoint.Presentations.Open(ppt_path, ReadOnly=True, Untitled=False, WithWindow=False)
slide_count = presentation.Slides.Count
print(f"Found {slide_count} slides in presentation")
if slide_count == 0:
print("Warning: Presentation contains no slides")
return images
# Get presentation dimensions for proper screenshot sizing
slide_width = presentation.PageSetup.SlideWidth
slide_height = presentation.PageSetup.SlideHeight
# Create a temporary directory for storing slide images
temp_dir = os.path.abspath(tempfile.mkdtemp())
#temp_dir= r"C:\Users\Public\Public Temp Pictures"
print(f"Created temporary directory: {temp_dir}")
# Verify that the directory exists
if not os.path.exists(temp_dir):
raise Exception(f"Failed to create temporary directory: {temp_dir}")
for i in range(1, slide_count + 1):
try:
slide = presentation.Slides(i)
# Export slide to temporary image file
temp_image_path = os.path.normpath(os.path.join(temp_dir, f"slide_{i}.png"))
print(f"Exporting slide {i} to {temp_image_path}")
# Export the slide as PNG
slide.Export(temp_image_path, "png", slide_width, slide_height)
print(f"Exported slide {i} to {temp_image_path}")
# Load the exported image
if os.path.exists(temp_image_path):
try:
img = Image.open(open(temp_image_path,'r'))
print(f"Successfully opened image for slide {i}")
images.append(img)
print(f"Extracted slide {i} from PPT using PowerPoint automation")
except Exception as open_error:
print(f"Warning new: Could not open image for slide {i}: {open_error}")
# Create a placeholder image for failed slides
img = Image.new('RGB', (1920, 1080), color='white')
from PIL import ImageDraw, ImageFont
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype("arial.ttf", 40)
except:
font = ImageFont.load_default()
draw.text((50, 50), f"Slide {i} - Image Open Failed", fill='red', font=font)
draw.text((50, 100), f"Error: {str(open_error)[:100]}", fill='black', font=font)
images.append(img)
# Clean up temporary file
try:
os.remove(temp_image_path)
print(f"Cleaned up temporary file for slide {i}")
except Exception as cleanup_error:
print(f"Warning: Could not clean up temporary file for slide {i}: {cleanup_error}")
else:
print(f"Warning: Failed to export slide {i} - file not found")
# Create a placeholder image for failed slides
img = Image.new('RGB', (1920, 1080), color='white')
from PIL import ImageDraw, ImageFont
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype("arial.ttf", 40)
except:
font = ImageFont.load_default()
draw.text((50, 50), f"Slide {i} - Export Failed", fill='red', font=font)
draw.text((50, 100), "Error: File not found", fill='black', font=font)
images.append(img)
except Exception as slide_error:
print(f"Warning: Could not extract slide {i}: {slide_error}")
# Create a placeholder image for failed slides
img = Image.new('RGB', (1920, 1080), color='white')
from PIL import ImageDraw, ImageFont
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype("arial.ttf", 40)
except:
font = ImageFont.load_default()
draw.text((50, 50), f"Slide {i} - Export Failed", fill='red', font=font)
draw.text((50, 100), f"Error: {str(slide_error)[:100]}", fill='black', font=font)
images.append(img)
# Clean up temporary directory
try:
os.rmdir(temp_dir)
print("Cleaned up temporary directory")
except Exception as cleanup_error:
print(f"Warning: Could not clean up temporary directory: {cleanup_error}")
except Exception as e:
error_msg = str(e)
if "PowerPoint" in error_msg and "not found" in error_msg.lower():
raise Exception(f"PowerPoint application not found. Please ensure Microsoft PowerPoint is installed.\n\n"
f"Error details: {error_msg}")
else:
raise Exception(f"PowerPoint automation failed: {error_msg}")
finally:
# Clean up COM objects
try:
if presentation is not None:
presentation.Close()
if powerpoint is not None:
powerpoint.Quit()
pythoncom.CoUninitialize()
except:
pass
return images
Now heres the issue, I am having issues with opening the image files with PIL:
img = image.open(filename, 'rb')
I get this following error:
Warning new: Could not open image for slide 2: cannot identify image file <_io.BufferedReader name='C:\Users\ZAHAB~1.KHA\AppData\Local\Temp\tmpnjvxai7k\slide_2.png'>
I'm not sure why, I have tried using:
img = Image.open(open(temp_image_path, 'r'))
but that did not work either. I also tried using cv2, but I had no luck with that either
Note that everything is encrypted, the PPT files, even the image files that are stored in the temp folder. Could this be a part of the reason why I'm facing this issue?
img = Image.open(open(temp_image_path,'r'))Why are you wrapping a call toopen()inside another call toopen()?Image.opengives me messagecannot identify image fileonly when I try to open file which is not image - ie. text file. Or when file is empty.