Comments (13)
Oops, should be remove_picture(*slide*, picture)
, not remove_picture(shapes,picture)
:)
I've updated above.
from python-pptx.
The workaround mentioned above is no longer functional. A new workaround would be appreciated!
from python-pptx.
@jhludwig: This should get it done as a temporary workaround. I'll leave this case open as a feature request to get the general case shapes.remove(shape) capability built.
Let me know how you go :)
from pptx import Presentation
from pptx.oxml import qn
def image_part_rId(picture):
"""
Return relationship id, e.g. 'rId9' corresponding to the image part
referenced by the picture shape *picture*.
"""
blip_elm = picture._element.blipFill[qn('a:blip')]
return blip_elm.get(qn('r:embed'))
def remove_picture(slide, picture):
"""
Remove *picture* shape from *slide*.
"""
# remove relationship to image part
rId = image_part_rId(picture)
remove_rel_with_rId(slide, rId)
# remove <pic> element
pic_elm = picture._element
spTree = pic_elm.getparent()
spTree.remove(pic_elm)
# remove picture from shapes
slide.shapes._values.remove(picture)
def remove_rel_with_rId(slide, rId):
"""
Remove the relationship identified by *rId* from *slide*.
"""
# get relationships list
rels = slide._relationships._values
# delete relationship with matching rId
for rel in rels:
if rel._rId == rId:
rels.remove(rel)
break
prs = Presentation('contains_picture.pptx')
slide = prs.slides[0]
picture = slide.shapes[0]
remove_picture(slide, picture)
prs.save('out.pptx')
from python-pptx.
This is awesome! Just tried it out and it was nearly perfect. One speed bump I hit -- for whatever reason, in my slide deck, the slide._relationships value was null, and so in the function remove_rel_with_rId that you specified, execution would blow up on the rels - slide._relationships._values line (pptxparse.py is my program):
File "pptxparse.py", line 119, in <module>
remove_picture(shapes, logopicture)
File "pptxparse.py", line 31, in remove_picture
remove_rel_with_rId(slide, rId)
File "pptxparse.py", line 44, in remove_rel_with_rId
rels = slide._relationships._values
AttributeError: '_ShapeCollection' object has no attribute '_relationships'
so i wrapped it with a "try" and all works ok for now:
try:
rels = slide._relationships._values
except AttributeError:
return
I coupled this with your other code to query the existing picture and strung it all together: get existing measurements, delete old picture, add a new picture with the old measurements. it works amazingly well!
thanks much. if there is anything i can do to help (on this issue or any other) let me know...
from python-pptx.
Note to self: implement shape delete as a method on each _BaseShape subclass, allowing distinct methods for each shape type and incremental addition of capability, with NotImplementedError on _BaseShape.delete(). E.g. _Picture.delete() executes code roughly equivalent to above. So once implemented, deleting a picture shape would be coded:
prs = Presentation('contains_picture.pptx')
picture = prs.slides[0].shapes[0] # or suitable to specific case
picture.delete()
prs.save('out.pptx')
from python-pptx.
Still no news? Deleting shapes is a basic feature but
slide.shapes._values.remove(picture)
cannot be performed (SlideShapes object has no attribute _values)
from python-pptx.
I am also looking for a solution to this problem.
from python-pptx.
As far as I know, deleting a picture consists in this list of steps:
- In slide XML file
- find the shape in the slide (type = <p:pic>)
- keep the reference to the image relationship (<p:pic> -> <p:blipFill> -> <a:blip>, attribute r:embed)
- delete the <p:pic> item
- in slide relationship XML file
- find the item whose Id attribute matches the previous reference
- keep the reference to the image (attribute Target)
- delete the item
- delete the image matching the previous target
HOWEVER if two shapes A and B have a reference to the same image, deleting it in A will result in invalid image for B.
So either do not delete the image file (that what Apache POI does), or remove it only if unused anywhere else (like, keeping a dict with image reference mapped to a counter??).
from python-pptx.
@Lasconik Yes, you see the complexity involved.
The details of relationships are abstracted out into the pptx.opc sub-package; so things like looking up an image part by the r:Id used in the pic element is accomplished with calls like:
image_part = shape.part.related_parts[rId]
Also in the opc
subpackage is the OpcPackage
class, which represents all the parts and all their relationships. Basically it's the .pptx file once opened.
A reference to the package can be gotten from a part:
package = shape.part.package
And all the relationships in the package can be accessed from there:
for rel in package.iter_rels():
if rel.target is the image file:
usage count += 1
So I'd be inclined to have it just traverse all the rels when needed rather than try to maintain a synchronized dictionary or something that you have to remember to update.
from python-pptx.
Has their been any progress on this? I got distracted because of x-mas and haven't accomplished anything myself. I just want to make sure I don't recreate the wheel when I start working on this again.
from python-pptx.
I haven't seen anything come through on it. I expect you're clear to go :)
from python-pptx.
Hello! Has this feature been updated?
from python-pptx.
Is that feature shapes.remove() available now?
from python-pptx.
Related Issues (20)
- How to extract CategoryAxis class names from a chart in a PowerPoint? HOT 9
- AttributeError: module 'collections' has no attribute 'Container' HOT 3
- GEnerative AI Inclusion
- Hyper Link to external sources HOT 2
- Convert PPT file to Python code HOT 2
- Second label as percentage - possible to visualize?
- `add_movie` corrupts powerpoint file when a non-openxml feature is used in animations HOT 2
- python pptx not extracting all the text from the slide HOT 1
- Delete slides HOT 3
- ValueError: ZIP does not support timestamps before 1980 HOT 1
- Failed to run after packaging
- condition before inserting image in placholde
- Slide duplicate Microsoft office interprets python-pptx powerpoint files as corrupted
- Cant put the hyperlink on the chart
- Save Slide as Image HOT 2
- Local PDF to PowerPoint Converter with LLM Summarization
- Is it possible to add support for "/select,file:///..." URIs? HOT 3
- Convert PPTX slide to Image HOT 1
- How to embed an .h3d (Hyperworks output file) file? HOT 3
- Line char None values
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from python-pptx.