python-pptx:用另一张图片替换一张图片

ljw*_*ker 5 python-pptx

我刚刚偶然发现了这个,它看起来非常有用。我找到了一些操作幻灯片等的示例,我的特定用例基本上涉及用不同的图像文件替换给定演示文稿中的一堆图像,但我想保留大部分元数据,例如位置、大小等。

我认为这个问题本质上更通用,更像是“python-pptx 框架内的逻辑流程是什么?”。简单地用新的文件指针替换文件指针肯定会错过标记,但对我来说,是否有可以轻松存储和重新应用的图片属性,或者其他什么方法可能最有意义地拥有代码,这对我来说并不明显以后合作起来会更容易...

任何建议表示赞赏;-)

更新:尝试了以下分配,_blob但它似乎不起作用,或者也许我错过了一些简单的事情?

#!/usr/bin/env python3

import pptx
import hashlib

prs = pptx.Presentation('hack.pptx')
newImgFilename = "gray.jpg"
img2 = pptx.parts.image.Image.from_file(newImgFilename)

print(hashlib.sha224(prs.slides[0].shapes[2].image._blob).hexdigest())
print(hashlib.sha224(img2._blob).hexdigest())
### these two should be different


prs.slides[0].shapes[2].image._blob = img2._blob
print(hashlib.sha224(prs.slides[0].shapes[2].image._blob).hexdigest())
### now this should be the value from img2, but it's not... 
Run Code Online (Sandbox Code Playgroud)

2023 年 1 月更新(工作代码):

#!/usr/bin/python3

import pptx

smallfile = "small.jpg"

# open presentation
prs = pptx.Presentation('test.pptx')

# create new image part from new image file
new_pptx_img = pptx.parts.image.Image.from_file(smallfile)

# obviously have to figure out what image you're actually changing...
img_shape = prs.slides[0].shapes[0]  

# get part and rId from shape we need to change
slide_part, rId = img_shape.part, img_shape._element.blip_rId
image_part = slide_part.related_part(rId)

# overwrite old blob info with new blob info
image_part.blob = new_pptx_img._blob

# save it
prs.save('changed.pptx')
Run Code Online (Sandbox Code Playgroud)

sca*_*nny 5

文件.pptx是一个 zip 存档。它的格式由开放打包约定 (OPC) 指定,文件.docx也是如此.xlsx。在 OPC 术语中,zip 存档称为“包”。

演示文稿中出现的图像“文件”的字节.pptx作为 zip 存档的独特“成员”存储在包中,可能位于类似ppt/media/image1.png. 不需要太多的窥探就能在那里找到它。

用于显示图像的其余信息(例如位置和大小)存储在其他地方。因此,只需用新的图像字节替换现有的图像字节,您就可以取得一定的进展。

您可以预见到一些挑战。

  1. 您需要确定哪个图像成员(例如 ppt/media/image42.png)与哪张幻灯片上的哪种图片形状相匹配。

  2. 如果长宽比不完全相同,则生成的图片将在一个维度或另一个维度上出现“拉伸”。

一般来说,您可以通过操纵 zip 存档或让python-pptx您尽可能地解决问题,然后深入研究内部结构以完成剩下的工作。

如果您用于python-pptx获取对图片形状的引用,picture.image将为您提供Image其包含的图像的对象。该类的代码位于: https: //github.com/scanny/python-pptx/blob/master/pptx/parts/image.py#L139

我会尝试分配新的图像字节然后Image._blob保存,看看会发生什么。如果需要的话,您用来到达那里的图片形状的大小和位置可以调整以适应新的宽高比,并且走这条路线可以让我们python-pptx处理所有包装细节,例如更改包中的哪个图像文件等等。

之后,您需要通过了解现有代码的工作原理并了解可以做什么来解决任何其他挑战。如果你走这条路,你可以在新问题出现时提出。


更新:好的,看起来该Image._blob项目没有被写入,它需要被写入ImagePart._blobImage._blob粗略地说,只是一个只读“副本”)。

shape = {picture shape of interest}
slide_part, rId = shape.part, shape._element.blip_rId
image_part = slide_part.related_parts[rId]
image_part.blob = new_blob
Run Code Online (Sandbox Code Playgroud)