Extract image position from .docx file using python-docx

You can also inspect paragraphs with a simple loop, and check which xml contains an image (for example if an xml contains "graphicData"), that is which is an image container (you can do the same with runs):

from docx import Document

image_paragraphs = []
doc = Document(path_to_docx)
for par in doc.paragraphs:
    if 'graphicData' in par._p.xml:
        image_paragraphs.append(par)

Than you unzip docx file, images are in the "images" folder, and they are in the same order as they will be in the image_paragraphs list. On every paragraph element you have many options how to change it. If you want to extract img process it and than insert it in the same place, than

paragraph.clear()
paragraph.add_run('your description, if needed')
run = paragraph.runs[0]
run.add_picture(path_to_pic, width, height)

This operation is not directly supported by the API.

However, if you're willing to dig into the internals a bit and use the underlying lxml API it's possible.

The general approach would be to access the ImagePart instance corresponding to the picture you want to inspect and modify, then read and write the ._blob attribute (which holds the image file as bytes).

This specimen XML might be helpful: http://python-docx.readthedocs.io/en/latest/dev/analysis/features/shapes/picture.html#specimen-xml

From the inline shape containing the picture, you get the <a:blip> element with this:

blip = inline_shape._inline.graphic.graphicData.pic.blipFill.blip

The relationship id (r:id generally, but r:embed in this case) is available at:

rId = blip.embed

Then you can get the image part from the document part

document_part = document.part
image_part = document_part.related_parts[rId]

And then the binary image is available for read and write on ._blob.

If you write a new blob, it will replace the prior image when saved.

You probably want to get it working with a single image and get a feel for it before scaling up to multiple images in a single document.

There might be one or two image characteristics that are cached, so you might not get all the finer points working until you save and reload the file, so just be alert for that.

Not for the faint of heart as you can see, but should work if you want it bad enough and can trace through the code a bit :)